get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 86836,
    "url": "http://patchwork.dpdk.org/api/patches/86836/?format=api",
    "web_url": "http://patchwork.dpdk.org/project/dpdk/patch/20210118214026.12009-3-akozyrev@nvidia.com/",
    "project": {
        "id": 1,
        "url": "http://patchwork.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": "<20210118214026.12009-3-akozyrev@nvidia.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/20210118214026.12009-3-akozyrev@nvidia.com",
    "date": "2021-01-18T21:40:26",
    "name": "[v9,2/2] app/testpmd: add support for modify field flow action",
    "commit_ref": null,
    "pull_url": null,
    "state": "accepted",
    "archived": true,
    "hash": "a7536ee93ab14631dd8178824e11ccef870ab3c1",
    "submitter": {
        "id": 1873,
        "url": "http://patchwork.dpdk.org/api/people/1873/?format=api",
        "name": "Alexander Kozyrev",
        "email": "akozyrev@nvidia.com"
    },
    "delegate": {
        "id": 319,
        "url": "http://patchwork.dpdk.org/api/users/319/?format=api",
        "username": "fyigit",
        "first_name": "Ferruh",
        "last_name": "Yigit",
        "email": "ferruh.yigit@amd.com"
    },
    "mbox": "http://patchwork.dpdk.org/project/dpdk/patch/20210118214026.12009-3-akozyrev@nvidia.com/mbox/",
    "series": [
        {
            "id": 14821,
            "url": "http://patchwork.dpdk.org/api/series/14821/?format=api",
            "web_url": "http://patchwork.dpdk.org/project/dpdk/list/?series=14821",
            "date": "2021-01-18T21:40:24",
            "name": "generic modify rte flow action support",
            "version": 9,
            "mbox": "http://patchwork.dpdk.org/series/14821/mbox/"
        }
    ],
    "comments": "http://patchwork.dpdk.org/api/patches/86836/comments/",
    "check": "fail",
    "checks": "http://patchwork.dpdk.org/api/patches/86836/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 CAC71A0A03;\n\tMon, 18 Jan 2021 22:40:42 +0100 (CET)",
            "from [217.70.189.124] (localhost [127.0.0.1])\n\tby mails.dpdk.org (Postfix) with ESMTP id 8791A140ED9;\n\tMon, 18 Jan 2021 22:40:37 +0100 (CET)",
            "from mellanox.co.il (mail-il-dmz.mellanox.com [193.47.165.129])\n by mails.dpdk.org (Postfix) with ESMTP id 98B03140EBF\n for <dev@dpdk.org>; Mon, 18 Jan 2021 22:40:34 +0100 (CET)",
            "from Internal Mail-Server by MTLPINE1 (envelope-from\n akozyrev@nvidia.com) with SMTP; 18 Jan 2021 23:40:29 +0200",
            "from nvidia.com (pegasus02.mtr.labs.mlnx [10.210.16.122])\n by labmailer.mlnx (8.13.8/8.13.8) with ESMTP id 10ILeS5n008977;\n Mon, 18 Jan 2021 23:40:29 +0200"
        ],
        "From": "Alexander Kozyrev <akozyrev@nvidia.com>",
        "To": "dev@dpdk.org",
        "Cc": "viacheslavo@nvidia.com, orika@nvidia.com, thomas@monjalon.net,\n ferruh.yigit@intel.com, andrew.rybchenko@oktetlabs.ru,\n jerinjacobk@gmail.com, ajit.khaparde@broadcom.com",
        "Date": "Mon, 18 Jan 2021 21:40:26 +0000",
        "Message-Id": "<20210118214026.12009-3-akozyrev@nvidia.com>",
        "X-Mailer": "git-send-email 2.24.1",
        "In-Reply-To": "<20210118214026.12009-1-akozyrev@nvidia.com>",
        "References": "<20210118161825.31516-1-akozyrev@nvidia.com>\n <20210118214026.12009-1-akozyrev@nvidia.com>",
        "MIME-Version": "1.0",
        "Content-Transfer-Encoding": "8bit",
        "Subject": "[dpdk-dev] [PATCH v9 2/2] app/testpmd: add support for modify field\n flow action",
        "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",
        "Sender": "\"dev\" <dev-bounces@dpdk.org>"
    },
    "content": "Add support for the RTE_FLOW_ACTION_MODIFY_FIELD to the testpmd.\nImplement CLI to create the modify_field action and supply all the\nneeded parameters to modify an arbitrary packet field (as well as\nmark, tag or metadata) with data from another field or immediate\nvalue.\n\nExample of the flow is the following:\nflow create 0 egress group 1 pattern eth / ipv4 / udp / end\n  actions modify_field op set dst_type tag dst_level 2 dst_offset 8\n          src_type gtp_teid src_level 0 src_offset 0 width 16 / end\n\nThis flow copies 16 bits from the second Tag in the Tags array\ninto the outermost GTP TEID packet header field. 8 bits of the\nTag are skipped as indicated by the dst_offset action parameter.\n\nop, dst_type, src_type and width are the mandatory parameters to\nspecify. Levels and offset are 0 by default if they are not\noverridden by a user. The operation can be set, add or sub.\n\nSigned-off-by: Alexander Kozyrev <akozyrev@nvidia.com>\nAcked-by: Ori Kam <orika@nvidia.com>\nAcked-by: Ajit Khaparde <ajit.khaparde@broadcom.com>\n\n---\nv1: Initial implementation.\nv2: Made dst_type, src_type and width only mandatory parameters.\nv3: Reworked to accomodate API change from copy_field to modify_field.\nv4: Renamed the mov operation to set.\n---\n app/test-pmd/cmdline_flow.c | 246 ++++++++++++++++++++++++++++++++++++\n 1 file changed, 246 insertions(+)",
    "diff": "diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c\nindex 37b10e61bf..aa5ccbbcd7 100644\n--- a/app/test-pmd/cmdline_flow.c\n+++ b/app/test-pmd/cmdline_flow.c\n@@ -408,6 +408,19 @@ enum index {\n \tACTION_SAMPLE_INDEX_VALUE,\n \tACTION_SHARED,\n \tSHARED_ACTION_ID2PTR,\n+\tACTION_MODIFY_FIELD,\n+\tACTION_MODIFY_FIELD_OP,\n+\tACTION_MODIFY_FIELD_OP_VALUE,\n+\tACTION_MODIFY_FIELD_DST_TYPE,\n+\tACTION_MODIFY_FIELD_DST_TYPE_VALUE,\n+\tACTION_MODIFY_FIELD_DST_LEVEL,\n+\tACTION_MODIFY_FIELD_DST_OFFSET,\n+\tACTION_MODIFY_FIELD_SRC_TYPE,\n+\tACTION_MODIFY_FIELD_SRC_TYPE_VALUE,\n+\tACTION_MODIFY_FIELD_SRC_LEVEL,\n+\tACTION_MODIFY_FIELD_SRC_OFFSET,\n+\tACTION_MODIFY_FIELD_SRC_VALUE,\n+\tACTION_MODIFY_FIELD_WIDTH,\n };\n \n /** Maximum size for pattern in struct rte_flow_item_raw. */\n@@ -561,6 +574,22 @@ struct rte_flow_action_count sample_count[RAW_SAMPLE_CONFS_MAX_NUM];\n struct rte_flow_action_port_id sample_port_id[RAW_SAMPLE_CONFS_MAX_NUM];\n struct rte_flow_action_raw_encap sample_encap[RAW_SAMPLE_CONFS_MAX_NUM];\n \n+static const char *const modify_field_ops[] = {\n+\t\"set\", \"add\", \"sub\", NULL\n+};\n+\n+static const char *const modify_field_ids[] = {\n+\t\"start\", \"mac_dst\", \"mac_src\",\n+\t\"vlan_type\", \"vlan_id\", \"mac_type\",\n+\t\"ipv4_dscp\", \"ipv4_ttl\", \"ipv4_src\", \"ipv4_dst\",\n+\t\"ipv6_hoplimit\", \"ipv6_src\", \"ipv6_dst\",\n+\t\"tcp_port_src\", \"tcp_port_dst\",\n+\t\"tcp_seq_num\", \"tcp_ack_num\", \"tcp_flags\",\n+\t\"udp_port_src\", \"udp_port_dst\",\n+\t\"vxlan_vni\", \"geneve_vni\", \"gtp_teid\",\n+\t\"tag\", \"mark\", \"meta\", \"pointer\", \"value\", NULL\n+};\n+\n /** Maximum number of subsequent tokens and arguments on the stack. */\n #define CTX_STACK_SIZE 16\n \n@@ -1306,6 +1335,7 @@ static const enum index next_action[] = {\n \tACTION_AGE,\n \tACTION_SAMPLE,\n \tACTION_SHARED,\n+\tACTION_MODIFY_FIELD,\n \tZERO,\n };\n \n@@ -1556,6 +1586,21 @@ static const enum index next_action_sample[] = {\n \tZERO,\n };\n \n+static const enum index action_modify_field_dst[] = {\n+\tACTION_MODIFY_FIELD_DST_LEVEL,\n+\tACTION_MODIFY_FIELD_DST_OFFSET,\n+\tACTION_MODIFY_FIELD_SRC_TYPE,\n+\tZERO,\n+};\n+\n+static const enum index action_modify_field_src[] = {\n+\tACTION_MODIFY_FIELD_SRC_LEVEL,\n+\tACTION_MODIFY_FIELD_SRC_OFFSET,\n+\tACTION_MODIFY_FIELD_SRC_VALUE,\n+\tACTION_MODIFY_FIELD_WIDTH,\n+\tZERO,\n+};\n+\n static int parse_set_raw_encap_decap(struct context *, const struct token *,\n \t\t\t\t     const char *, unsigned int,\n \t\t\t\t     void *, unsigned int);\n@@ -1638,6 +1683,14 @@ static int\n parse_vc_action_sample_index(struct context *ctx, const struct token *token,\n \t\t\t\tconst char *str, unsigned int len, void *buf,\n \t\t\t\tunsigned int size);\n+static int\n+parse_vc_modify_field_op(struct context *ctx, const struct token *token,\n+\t\t\t\tconst char *str, unsigned int len, void *buf,\n+\t\t\t\tunsigned int size);\n+static int\n+parse_vc_modify_field_id(struct context *ctx, const struct token *token,\n+\t\t\t\tconst char *str, unsigned int len, void *buf,\n+\t\t\t\tunsigned int size);\n static int parse_destroy(struct context *, const struct token *,\n \t\t\t const char *, unsigned int,\n \t\t\t void *, unsigned int);\n@@ -1722,6 +1775,10 @@ static int comp_set_raw_index(struct context *, const struct token *,\n \t\t\t      unsigned int, char *, unsigned int);\n static int comp_set_sample_index(struct context *, const struct token *,\n \t\t\t      unsigned int, char *, unsigned int);\n+static int comp_set_modify_field_op(struct context *, const struct token *,\n+\t\t\t      unsigned int, char *, unsigned int);\n+static int comp_set_modify_field_id(struct context *, const struct token *,\n+\t\t\t      unsigned int, char *, unsigned int);\n \n /** Token definitions. */\n static const struct token token_list[] = {\n@@ -4037,6 +4094,103 @@ static const struct token token_list[] = {\n \t\t.call = parse_vc_action_raw_decap_index,\n \t\t.comp = comp_set_raw_index,\n \t},\n+\t[ACTION_MODIFY_FIELD] = {\n+\t\t.name = \"modify_field\",\n+\t\t.help = \"modify destination field with data from source field\",\n+\t\t.priv = PRIV_ACTION(MODIFY_FIELD,\n+\t\t\tsizeof(struct rte_flow_action_modify_field)),\n+\t\t.next = NEXT(NEXT_ENTRY(ACTION_MODIFY_FIELD_OP)),\n+\t\t.call = parse_vc,\n+\t},\n+\t[ACTION_MODIFY_FIELD_OP] = {\n+\t\t.name = \"op\",\n+\t\t.help = \"operation type\",\n+\t\t.next = NEXT(NEXT_ENTRY(ACTION_MODIFY_FIELD_DST_TYPE),\n+\t\t\tNEXT_ENTRY(ACTION_MODIFY_FIELD_OP_VALUE)),\n+\t\t.call = parse_vc_conf,\n+\t},\n+\t[ACTION_MODIFY_FIELD_OP_VALUE] = {\n+\t\t.name = \"{operation}\",\n+\t\t.help = \"operation type value\",\n+\t\t.call = parse_vc_modify_field_op,\n+\t\t.comp = comp_set_modify_field_op,\n+\t},\n+\t[ACTION_MODIFY_FIELD_DST_TYPE] = {\n+\t\t.name = \"dst_type\",\n+\t\t.help = \"destination field type\",\n+\t\t.next = NEXT(action_modify_field_dst,\n+\t\t\tNEXT_ENTRY(ACTION_MODIFY_FIELD_DST_TYPE_VALUE)),\n+\t\t.call = parse_vc_conf,\n+\t},\n+\t[ACTION_MODIFY_FIELD_DST_TYPE_VALUE] = {\n+\t\t.name = \"{dst_type}\",\n+\t\t.help = \"destination field type value\",\n+\t\t.call = parse_vc_modify_field_id,\n+\t\t.comp = comp_set_modify_field_id,\n+\t},\n+\t[ACTION_MODIFY_FIELD_DST_LEVEL] = {\n+\t\t.name = \"dst_level\",\n+\t\t.help = \"destination field level\",\n+\t\t.next = NEXT(action_modify_field_dst, NEXT_ENTRY(UNSIGNED)),\n+\t\t.args = ARGS(ARGS_ENTRY(struct rte_flow_action_modify_field,\n+\t\t\t\t\tdst.level)),\n+\t\t.call = parse_vc_conf,\n+\t},\n+\t[ACTION_MODIFY_FIELD_DST_OFFSET] = {\n+\t\t.name = \"dst_offset\",\n+\t\t.help = \"destination field bit offset\",\n+\t\t.next = NEXT(action_modify_field_dst, NEXT_ENTRY(UNSIGNED)),\n+\t\t.args = ARGS(ARGS_ENTRY(struct rte_flow_action_modify_field,\n+\t\t\t\t\tdst.offset)),\n+\t\t.call = parse_vc_conf,\n+\t},\n+\t[ACTION_MODIFY_FIELD_SRC_TYPE] = {\n+\t\t.name = \"src_type\",\n+\t\t.help = \"source field type\",\n+\t\t.next = NEXT(action_modify_field_src,\n+\t\t\tNEXT_ENTRY(ACTION_MODIFY_FIELD_SRC_TYPE_VALUE)),\n+\t\t.call = parse_vc_conf,\n+\t},\n+\t[ACTION_MODIFY_FIELD_SRC_TYPE_VALUE] = {\n+\t\t.name = \"{src_type}\",\n+\t\t.help = \"source field type value\",\n+\t\t.call = parse_vc_modify_field_id,\n+\t\t.comp = comp_set_modify_field_id,\n+\t},\n+\t[ACTION_MODIFY_FIELD_SRC_LEVEL] = {\n+\t\t.name = \"src_level\",\n+\t\t.help = \"source field level\",\n+\t\t.next = NEXT(action_modify_field_src, NEXT_ENTRY(UNSIGNED)),\n+\t\t.args = ARGS(ARGS_ENTRY(struct rte_flow_action_modify_field,\n+\t\t\t\t\tsrc.level)),\n+\t\t.call = parse_vc_conf,\n+\t},\n+\t[ACTION_MODIFY_FIELD_SRC_OFFSET] = {\n+\t\t.name = \"src_offset\",\n+\t\t.help = \"source field bit offset\",\n+\t\t.next = NEXT(action_modify_field_src, NEXT_ENTRY(UNSIGNED)),\n+\t\t.args = ARGS(ARGS_ENTRY(struct rte_flow_action_modify_field,\n+\t\t\t\t\tsrc.offset)),\n+\t\t.call = parse_vc_conf,\n+\t},\n+\t[ACTION_MODIFY_FIELD_SRC_VALUE] = {\n+\t\t.name = \"src_value\",\n+\t\t.help = \"source immediate value\",\n+\t\t.next = NEXT(NEXT_ENTRY(ACTION_MODIFY_FIELD_WIDTH),\n+\t\t\tNEXT_ENTRY(UNSIGNED)),\n+\t\t.args = ARGS(ARGS_ENTRY(struct rte_flow_action_modify_field,\n+\t\t\t\t\tsrc.value)),\n+\t\t.call = parse_vc_conf,\n+\t},\n+\t[ACTION_MODIFY_FIELD_WIDTH] = {\n+\t\t.name = \"width\",\n+\t\t.help = \"number of bits to copy\",\n+\t\t.next = NEXT(NEXT_ENTRY(ACTION_NEXT),\n+\t\t\tNEXT_ENTRY(UNSIGNED)),\n+\t\t.args = ARGS(ARGS_ENTRY(struct rte_flow_action_modify_field,\n+\t\t\t\t\twidth)),\n+\t\t.call = parse_vc_conf,\n+\t},\n \t/* Top level command. */\n \t[SET] = {\n \t\t.name = \"set\",\n@@ -5960,6 +6114,62 @@ parse_vc_action_sample_index(struct context *ctx, const struct token *token,\n \treturn len;\n }\n \n+/** Parse operation for modify_field command. */\n+static int\n+parse_vc_modify_field_op(struct context *ctx, const struct token *token,\n+\t\t\t const char *str, unsigned int len, void *buf,\n+\t\t\t unsigned int size)\n+{\n+\tstruct rte_flow_action_modify_field *action_modify_field;\n+\tunsigned int i;\n+\n+\t(void)token;\n+\t(void)buf;\n+\t(void)size;\n+\tif (ctx->curr != ACTION_MODIFY_FIELD_OP_VALUE)\n+\t\treturn -1;\n+\tfor (i = 0; modify_field_ops[i]; ++i)\n+\t\tif (!strcmp_partial(modify_field_ops[i], str, len))\n+\t\t\tbreak;\n+\tif (!modify_field_ops[i])\n+\t\treturn -1;\n+\tif (!ctx->object)\n+\t\treturn len;\n+\taction_modify_field = ctx->object;\n+\taction_modify_field->operation = (enum rte_flow_modify_op)i;\n+\treturn len;\n+}\n+\n+/** Parse id for modify_field command. */\n+static int\n+parse_vc_modify_field_id(struct context *ctx, const struct token *token,\n+\t\t\t const char *str, unsigned int len, void *buf,\n+\t\t\t unsigned int size)\n+{\n+\tstruct rte_flow_action_modify_field *action_modify_field;\n+\tunsigned int i;\n+\n+\t(void)token;\n+\t(void)buf;\n+\t(void)size;\n+\tif (ctx->curr != ACTION_MODIFY_FIELD_DST_TYPE_VALUE &&\n+\t\tctx->curr != ACTION_MODIFY_FIELD_SRC_TYPE_VALUE)\n+\t\treturn -1;\n+\tfor (i = 0; modify_field_ids[i]; ++i)\n+\t\tif (!strcmp_partial(modify_field_ids[i], str, len))\n+\t\t\tbreak;\n+\tif (!modify_field_ids[i])\n+\t\treturn -1;\n+\tif (!ctx->object)\n+\t\treturn len;\n+\taction_modify_field = ctx->object;\n+\tif (ctx->curr == ACTION_MODIFY_FIELD_DST_TYPE_VALUE)\n+\t\taction_modify_field->dst.field = (enum rte_flow_field_id)i;\n+\telse\n+\t\taction_modify_field->src.field = (enum rte_flow_field_id)i;\n+\treturn len;\n+}\n+\n /** Parse tokens for destroy command. */\n static int\n parse_destroy(struct context *ctx, const struct token *token,\n@@ -7029,6 +7239,42 @@ comp_set_sample_index(struct context *ctx, const struct token *token,\n \treturn nb;\n }\n \n+/** Complete operation for modify_field command. */\n+static int\n+comp_set_modify_field_op(struct context *ctx, const struct token *token,\n+\t\t   unsigned int ent, char *buf, unsigned int size)\n+{\n+\tuint16_t idx = 0;\n+\n+\tRTE_SET_USED(ctx);\n+\tRTE_SET_USED(token);\n+\tfor (idx = 0; modify_field_ops[idx]; ++idx)\n+\t\t;\n+\tif (!buf)\n+\t\treturn idx + 1;\n+\tif (ent < idx)\n+\t\treturn strlcpy(buf, modify_field_ops[ent], size);\n+\treturn -1;\n+}\n+\n+/** Complete field id for modify_field command. */\n+static int\n+comp_set_modify_field_id(struct context *ctx, const struct token *token,\n+\t\t   unsigned int ent, char *buf, unsigned int size)\n+{\n+\tuint16_t idx = 0;\n+\n+\tRTE_SET_USED(ctx);\n+\tRTE_SET_USED(token);\n+\tfor (idx = 0; modify_field_ids[idx]; ++idx)\n+\t\t;\n+\tif (!buf)\n+\t\treturn idx + 1;\n+\tif (ent < idx)\n+\t\treturn strlcpy(buf, modify_field_ids[ent], size);\n+\treturn -1;\n+}\n+\n /** Internal context. */\n static struct context cmd_flow_context;\n \n",
    "prefixes": [
        "v9",
        "2/2"
    ]
}