get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 64765,
    "url": "http://patchwork.dpdk.org/api/patches/64765/",
    "web_url": "http://patchwork.dpdk.org/project/dpdk/patch/c4ee5402ddf6957872339a3163017c9b64cc0d23.1579168182.git.jackmin@mellanox.com/",
    "project": {
        "id": 1,
        "url": "http://patchwork.dpdk.org/api/projects/1/",
        "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": "<c4ee5402ddf6957872339a3163017c9b64cc0d23.1579168182.git.jackmin@mellanox.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/c4ee5402ddf6957872339a3163017c9b64cc0d23.1579168182.git.jackmin@mellanox.com",
    "date": "2020-01-16T10:14:15",
    "name": "[3/5] app/testpmd: new flow dump CLI",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "256e86b1e1400eadbcda62d1baab0ab48e0a996b",
    "submitter": {
        "id": 1065,
        "url": "http://patchwork.dpdk.org/api/people/1065/",
        "name": "Xiaoyu Min",
        "email": "jackmin@mellanox.com"
    },
    "delegate": {
        "id": 319,
        "url": "http://patchwork.dpdk.org/api/users/319/",
        "username": "fyigit",
        "first_name": "Ferruh",
        "last_name": "Yigit",
        "email": "ferruh.yigit@intel.com"
    },
    "mbox": "http://patchwork.dpdk.org/project/dpdk/patch/c4ee5402ddf6957872339a3163017c9b64cc0d23.1579168182.git.jackmin@mellanox.com/mbox/",
    "series": [
        {
            "id": 8154,
            "url": "http://patchwork.dpdk.org/api/series/8154/",
            "web_url": "http://patchwork.dpdk.org/project/dpdk/list/?series=8154",
            "date": "2020-01-16T10:14:12",
            "name": "ethdev: add API to dump device internal flow info",
            "version": 1,
            "mbox": "http://patchwork.dpdk.org/series/8154/mbox/"
        }
    ],
    "comments": "http://patchwork.dpdk.org/api/patches/64765/comments/",
    "check": "success",
    "checks": "http://patchwork.dpdk.org/api/patches/64765/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "List-Help": "<mailto:dev-request@dpdk.org?subject=help>",
        "Received": [
            "from dpdk.org (dpdk.org [92.243.14.124])\n\tby inbox.dpdk.org (Postfix) with ESMTP id 53008A0352;\n\tThu, 16 Jan 2020 11:16:08 +0100 (CET)",
            "from [92.243.14.124] (localhost [127.0.0.1])\n\tby dpdk.org (Postfix) with ESMTP id 3CEB31C1F1;\n\tThu, 16 Jan 2020 11:15:50 +0100 (CET)",
            "from git-send-mailer.rdmz.labs.mlnx (unknown [37.142.13.130])\n by dpdk.org (Postfix) with ESMTP id ABF2D1C1E1\n for <dev@dpdk.org>; Thu, 16 Jan 2020 11:15:45 +0100 (CET)"
        ],
        "X-Mailman-Version": "2.1.15",
        "Return-Path": "<dev-bounces@dpdk.org>",
        "List-Subscribe": "<https://mails.dpdk.org/listinfo/dev>,\n <mailto:dev-request@dpdk.org?subject=subscribe>",
        "To": "jerinjacobk@gmail.com, orika@mellanox.com, viacheslavo@mellanox.com,\n matan@mellanox.com, rasland@mellanox.com,\n Adrien Mazarguil <adrien.mazarguil@6wind.com>,\n Wenzhuo Lu <wenzhuo.lu@intel.com>, Jingjing Wu <jingjing.wu@intel.com>,\n Bernard Iremonger <bernard.iremonger@intel.com>",
        "Delivered-To": "patchwork@inbox.dpdk.org",
        "List-Id": "DPDK patches and discussions <dev.dpdk.org>",
        "References": "<cover.1579168182.git.jackmin@mellanox.com>",
        "List-Unsubscribe": "<https://mails.dpdk.org/options/dev>,\n <mailto:dev-request@dpdk.org?subject=unsubscribe>",
        "X-Original-To": "patchwork@inbox.dpdk.org",
        "Content-Transfer-Encoding": "8bit",
        "Message-Id": "\n <c4ee5402ddf6957872339a3163017c9b64cc0d23.1579168182.git.jackmin@mellanox.com>",
        "Precedence": "list",
        "Sender": "\"dev\" <dev-bounces@dpdk.org>",
        "Subject": "[dpdk-dev] [PATCH 3/5] app/testpmd: new flow dump CLI",
        "MIME-Version": "1.0",
        "List-Post": "<mailto:dev@dpdk.org>",
        "Date": "Thu, 16 Jan 2020 12:14:15 +0200",
        "In-Reply-To": "<cover.1579168182.git.jackmin@mellanox.com>",
        "X-BeenThere": "dev@dpdk.org",
        "X-Mailer": "git-send-email 2.21.0",
        "Errors-To": "dev-bounces@dpdk.org",
        "List-Archive": "<http://mails.dpdk.org/archives/dev/>",
        "Cc": "dev@dpdk.org,\n\tXueming Li <xuemingl@mellanox.com>",
        "From": "Xiaoyu Min <jackmin@mellanox.com>"
    },
    "content": "From: Xueming Li <xuemingl@mellanox.com>\n\nNew flow dump CLI to dump device internal representation information\nof flows into screen.\n\nSigned-off-by: Xueming Li <xuemingl@mellanox.com>\nSigned-off-by: Xiaoyu Min <jackmin@mellanox.com>\n---\n app/test-pmd/cmdline_flow.c | 91 +++++++++++++++++++++++++++++++++++++\n app/test-pmd/config.c       | 27 +++++++++++\n app/test-pmd/testpmd.h      |  1 +\n 3 files changed, 119 insertions(+)",
    "diff": "diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c\nindex 99dade7d8c..19336e5d42 100644\n--- a/app/test-pmd/cmdline_flow.c\n+++ b/app/test-pmd/cmdline_flow.c\n@@ -41,6 +41,7 @@ enum index {\n \tBOOLEAN,\n \tSTRING,\n \tHEX,\n+\tFILE_PATH,\n \tMAC_ADDR,\n \tIPV4_ADDR,\n \tIPV6_ADDR,\n@@ -63,6 +64,7 @@ enum index {\n \tCREATE,\n \tDESTROY,\n \tFLUSH,\n+\tDUMP,\n \tQUERY,\n \tLIST,\n \tISOLATE,\n@@ -631,6 +633,9 @@ struct buffer {\n \t\t\tuint32_t *rule;\n \t\t\tuint32_t rule_n;\n \t\t} destroy; /**< Destroy arguments. */\n+\t\tstruct {\n+\t\t\tchar file[128];\n+\t\t} dump; /**< Dump arguments. */\n \t\tstruct {\n \t\t\tuint32_t rule;\n \t\t\tstruct rte_flow_action action;\n@@ -685,6 +690,12 @@ static const enum index next_destroy_attr[] = {\n \tZERO,\n };\n \n+static const enum index next_dump_attr[] = {\n+\tFILE_PATH,\n+\tEND,\n+\tZERO,\n+};\n+\n static const enum index next_list_attr[] = {\n \tLIST_GROUP,\n \tEND,\n@@ -1374,6 +1385,9 @@ static int parse_destroy(struct context *, const struct token *,\n static int parse_flush(struct context *, const struct token *,\n \t\t       const char *, unsigned int,\n \t\t       void *, unsigned int);\n+static int parse_dump(struct context *, const struct token *,\n+\t\t      const char *, unsigned int,\n+\t\t      void *, unsigned int);\n static int parse_query(struct context *, const struct token *,\n \t\t       const char *, unsigned int,\n \t\t       void *, unsigned int);\n@@ -1401,6 +1415,9 @@ static int parse_string(struct context *, const struct token *,\n static int parse_hex(struct context *ctx, const struct token *token,\n \t\t\tconst char *str, unsigned int len,\n \t\t\tvoid *buf, unsigned int size);\n+static int parse_string0(struct context *, const struct token *,\n+\t\t\tconst char *, unsigned int,\n+\t\t\tvoid *, unsigned int);\n static int parse_mac_addr(struct context *, const struct token *,\n \t\t\t  const char *, unsigned int,\n \t\t\t  void *, unsigned int);\n@@ -1494,6 +1511,12 @@ static const struct token token_list[] = {\n \t\t.type = \"HEX\",\n \t\t.help = \"fixed string\",\n \t\t.call = parse_hex,\n+\t},\n+\t[FILE_PATH] = {\n+\t\t.name = \"{file path}\",\n+\t\t.type = \"STRING\",\n+\t\t.help = \"file path\",\n+\t\t.call = parse_string0,\n \t\t.comp = comp_none,\n \t},\n \t[MAC_ADDR] = {\n@@ -1555,6 +1578,7 @@ static const struct token token_list[] = {\n \t\t\t      CREATE,\n \t\t\t      DESTROY,\n \t\t\t      FLUSH,\n+\t\t\t      DUMP,\n \t\t\t      LIST,\n \t\t\t      QUERY,\n \t\t\t      ISOLATE)),\n@@ -1589,6 +1613,14 @@ static const struct token token_list[] = {\n \t\t.args = ARGS(ARGS_ENTRY(struct buffer, port)),\n \t\t.call = parse_flush,\n \t},\n+\t[DUMP] = {\n+\t\t.name = \"dump\",\n+\t\t.help = \"dump all flow rules to file\",\n+\t\t.next = NEXT(next_dump_attr, NEXT_ENTRY(PORT_ID)),\n+\t\t.args = ARGS(ARGS_ENTRY(struct buffer, args.dump.file),\n+\t\t\t     ARGS_ENTRY(struct buffer, port)),\n+\t\t.call = parse_dump,\n+\t},\n \t[QUERY] = {\n \t\t.name = \"query\",\n \t\t.help = \"query an existing flow rule\",\n@@ -5012,6 +5044,33 @@ parse_flush(struct context *ctx, const struct token *token,\n \treturn len;\n }\n \n+/** Parse tokens for dump command. */\n+static int\n+parse_dump(struct context *ctx, const struct token *token,\n+\t    const char *str, unsigned int len,\n+\t    void *buf, unsigned int size)\n+{\n+\tstruct buffer *out = buf;\n+\n+\t/* Token name must match. */\n+\tif (parse_default(ctx, token, str, len, NULL, 0) < 0)\n+\t\treturn -1;\n+\t/* Nothing else to do if there is no buffer. */\n+\tif (!out)\n+\t\treturn len;\n+\tif (!out->command) {\n+\t\tif (ctx->curr != DUMP)\n+\t\t\treturn -1;\n+\t\tif (sizeof(*out) > size)\n+\t\t\treturn -1;\n+\t\tout->command = ctx->curr;\n+\t\tctx->objdata = 0;\n+\t\tctx->object = out;\n+\t\tctx->objmask = NULL;\n+\t}\n+\treturn len;\n+}\n+\n /** Parse tokens for query command. */\n static int\n parse_query(struct context *ctx, const struct token *token,\n@@ -5409,6 +5468,35 @@ parse_hex(struct context *ctx, const struct token *token,\n \n }\n \n+/**\n+ * Parse a zero-ended string.\n+ */\n+static int\n+parse_string0(struct context *ctx, const struct token *token __rte_unused,\n+\t     const char *str, unsigned int len,\n+\t     void *buf, unsigned int size)\n+{\n+\tconst struct arg *arg_data = pop_args(ctx);\n+\n+\t/* Arguments are expected. */\n+\tif (!arg_data)\n+\t\treturn -1;\n+\tsize = arg_data->size;\n+\t/* Bit-mask fill is not supported. */\n+\tif (arg_data->mask || size < len + 1)\n+\t\tgoto error;\n+\tif (!ctx->object)\n+\t\treturn len;\n+\tbuf = (uint8_t *)ctx->object + arg_data->offset;\n+\tstrncpy(buf, str, len);\n+\tif (ctx->objmask)\n+\t\tmemset((uint8_t *)ctx->objmask + arg_data->offset, 0xff, len);\n+\treturn len;\n+error:\n+\tpush_args(ctx, arg_data);\n+\treturn -1;\n+}\n+\n /**\n  * Parse a MAC address.\n  *\n@@ -6068,6 +6156,9 @@ cmd_flow_parsed(const struct buffer *in)\n \tcase FLUSH:\n \t\tport_flow_flush(in->port);\n \t\tbreak;\n+\tcase DUMP:\n+\t\tport_flow_dump(in->port, in->args.dump.file);\n+\t\tbreak;\n \tcase QUERY:\n \t\tport_flow_query(in->port, in->args.query.rule,\n \t\t\t\t&in->args.query.action);\ndiff --git a/app/test-pmd/config.c b/app/test-pmd/config.c\nindex 9da1ffb034..1b4bdf7bf3 100644\n--- a/app/test-pmd/config.c\n+++ b/app/test-pmd/config.c\n@@ -1441,6 +1441,33 @@ port_flow_flush(portid_t port_id)\n \treturn ret;\n }\n \n+/** Dump all flow rules. */\n+int\n+port_flow_dump(portid_t port_id, const char *file_name)\n+{\n+\tint ret = 0;\n+\tFILE *file = stdout;\n+\tstruct rte_flow_error error;\n+\n+\tif (file_name && strlen(file_name)) {\n+\t\tfile = fopen(file_name, \"w\");\n+\t\tif (!file) {\n+\t\t\tprintf(\"Failed to create file %s: %s\\n\", file_name,\n+\t\t\t       strerror(errno));\n+\t\t\treturn -errno;\n+\t\t}\n+\t}\n+\tret = rte_flow_dev_dump(port_id, file, &error);\n+\tif (ret) {\n+\t\tport_flow_complain(&error);\n+\t\tprintf(\"Failed to dump flow: %s\\n\", strerror(-ret));\n+\t} else\n+\t\tprintf(\"Flow dump finished\\n\");\n+\tif (file_name && strlen(file_name))\n+\t\tfclose(file);\n+\treturn ret;\n+}\n+\n /** Query a flow rule. */\n int\n port_flow_query(portid_t port_id, uint32_t rule,\ndiff --git a/app/test-pmd/testpmd.h b/app/test-pmd/testpmd.h\nindex 857a11f8de..e1b9aba360 100644\n--- a/app/test-pmd/testpmd.h\n+++ b/app/test-pmd/testpmd.h\n@@ -734,6 +734,7 @@ int port_flow_create(portid_t port_id,\n \t\t     const struct rte_flow_action *actions);\n int port_flow_destroy(portid_t port_id, uint32_t n, const uint32_t *rule);\n int port_flow_flush(portid_t port_id);\n+int port_flow_dump(portid_t port_id, const char *file_name);\n int port_flow_query(portid_t port_id, uint32_t rule,\n \t\t    const struct rte_flow_action *action);\n void port_flow_list(portid_t port_id, uint32_t n, const uint32_t *group);\n",
    "prefixes": [
        "3/5"
    ]
}