get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 87923,
    "url": "https://patches.dpdk.org/api/patches/87923/?format=api",
    "web_url": "https://patches.dpdk.org/project/dpdk/patch/20210215162151.5655-2-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": "<20210215162151.5655-2-cristian.dumitrescu@intel.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/20210215162151.5655-2-cristian.dumitrescu@intel.com",
    "date": "2021-02-15T16:21:48",
    "name": "[2/5] pipeline: improve table entry parsing",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "4e54195be2439180c5725eadcda72903b285b267",
    "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/20210215162151.5655-2-cristian.dumitrescu@intel.com/mbox/",
    "series": [
        {
            "id": 15263,
            "url": "https://patches.dpdk.org/api/series/15263/?format=api",
            "web_url": "https://patches.dpdk.org/project/dpdk/list/?series=15263",
            "date": "2021-02-15T16:21:47",
            "name": "[1/5] pipeline: improve table entry helpers",
            "version": 1,
            "mbox": "https://patches.dpdk.org/series/15263/mbox/"
        }
    ],
    "comments": "https://patches.dpdk.org/api/patches/87923/comments/",
    "check": "success",
    "checks": "https://patches.dpdk.org/api/patches/87923/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 9AE16A054F;\n\tMon, 15 Feb 2021 17:22:04 +0100 (CET)",
            "from [217.70.189.124] (localhost [127.0.0.1])\n\tby mails.dpdk.org (Postfix) with ESMTP id 37DDD1606CC;\n\tMon, 15 Feb 2021 17:21:59 +0100 (CET)",
            "from mga01.intel.com (mga01.intel.com [192.55.52.88])\n by mails.dpdk.org (Postfix) with ESMTP id ED17B160684\n for <dev@dpdk.org>; Mon, 15 Feb 2021 17:21:55 +0100 (CET)",
            "from fmsmga008.fm.intel.com ([10.253.24.58])\n by fmsmga101.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384;\n 15 Feb 2021 08:21:54 -0800",
            "from silpixa00400573.ir.intel.com (HELO\n silpixa00400573.ger.corp.intel.com) ([10.237.223.107])\n by fmsmga008.fm.intel.com with ESMTP; 15 Feb 2021 08:21:53 -0800"
        ],
        "IronPort-SDR": [
            "\n kn6hmzKdktYED7erw7IiXaMR5eLWzuWRJg8FaWLzYAtB55O0cGEOrpXDWp4d1wbwpQ09aeOyGY\n /e5UwIQ6jFpw==",
            "\n 91qjobWU6L7iaO817eO81LKSRIEQL+c72Psn3RtTAs5J5cUIbWl4jPOVq/Tt4aY8xfK2pZhGE+\n t/7VwVWVq76Q=="
        ],
        "X-IronPort-AV": [
            "E=McAfee;i=\"6000,8403,9896\"; a=\"201892841\"",
            "E=Sophos;i=\"5.81,181,1610438400\"; d=\"scan'208\";a=\"201892841\"",
            "E=Sophos;i=\"5.81,181,1610438400\"; d=\"scan'208\";a=\"383421600\""
        ],
        "X-ExtLoop1": "1",
        "From": "Cristian Dumitrescu <cristian.dumitrescu@intel.com>",
        "To": "dev@dpdk.org",
        "Cc": "Venkata Suresh Kumar P <venkata.suresh.kumar.p@intel.com>,\n Churchill Khangar <churchill.khangar@intel.com>",
        "Date": "Mon, 15 Feb 2021 16:21:48 +0000",
        "Message-Id": "<20210215162151.5655-2-cristian.dumitrescu@intel.com>",
        "X-Mailer": "git-send-email 2.17.1",
        "In-Reply-To": "<20210215162151.5655-1-cristian.dumitrescu@intel.com>",
        "References": "<20210215162151.5655-1-cristian.dumitrescu@intel.com>",
        "Subject": "[dpdk-dev] [PATCH 2/5] pipeline: improve table entry parsing",
        "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": "Improve the table entry parsing: better code structure, enable parsing\nfor the key field masks, allow comments and empty lines in the table\nentry files.\n\nSigned-off-by: Cristian Dumitrescu <cristian.dumitrescu@intel.com>\nSigned-off-by: Venkata Suresh Kumar P <venkata.suresh.kumar.p@intel.com>\nSigned-off-by: Churchill Khangar <churchill.khangar@intel.com>\n---\n examples/pipeline/cli.c           |  21 +++-\n lib/librte_pipeline/rte_swx_ctl.c | 172 ++++++++++++++++++++----------\n lib/librte_pipeline/rte_swx_ctl.h |   7 +-\n 3 files changed, 141 insertions(+), 59 deletions(-)",
    "diff": "diff --git a/examples/pipeline/cli.c b/examples/pipeline/cli.c\nindex e97e12060..30c2dd34d 100644\n--- a/examples/pipeline/cli.c\n+++ b/examples/pipeline/cli.c\n@@ -881,14 +881,19 @@ cmd_pipeline_table_update(char **tokens,\n \tif (file_add)\n \t\tfor (line_id = 1; ; line_id++) {\n \t\t\tstruct rte_swx_table_entry *entry;\n+\t\t\tint is_blank_or_comment;\n \n \t\t\tif (fgets(line, 2048, file_add) == NULL)\n \t\t\t\tbreak;\n \n \t\t\tentry = rte_swx_ctl_pipeline_table_entry_read(p->ctl,\n \t\t\t\ttable_name,\n-\t\t\t\tline);\n+\t\t\t\tline,\n+\t\t\t\t&is_blank_or_comment);\n \t\t\tif (!entry) {\n+\t\t\t\tif (is_blank_or_comment)\n+\t\t\t\t\tcontinue;\n+\n \t\t\t\tsnprintf(out, out_size, MSG_FILE_ERR,\n \t\t\t\t\tfile_name_add, line_id);\n \t\t\t\tgoto error;\n@@ -911,14 +916,19 @@ cmd_pipeline_table_update(char **tokens,\n \tif (file_delete)\n \t\tfor (line_id = 1; ; line_id++) {\n \t\t\tstruct rte_swx_table_entry *entry;\n+\t\t\tint is_blank_or_comment;\n \n \t\t\tif (fgets(line, 2048, file_delete) == NULL)\n \t\t\t\tbreak;\n \n \t\t\tentry = rte_swx_ctl_pipeline_table_entry_read(p->ctl,\n \t\t\t\ttable_name,\n-\t\t\t\tline);\n+\t\t\t\tline,\n+\t\t\t\t&is_blank_or_comment);\n \t\t\tif (!entry) {\n+\t\t\t\tif (is_blank_or_comment)\n+\t\t\t\t\tcontinue;\n+\n \t\t\t\tsnprintf(out, out_size, MSG_FILE_ERR,\n \t\t\t\t\tfile_name_delete, line_id);\n \t\t\t\tgoto error;\n@@ -940,14 +950,19 @@ cmd_pipeline_table_update(char **tokens,\n \tif (file_default)\n \t\tfor (line_id = 1; ; line_id++) {\n \t\t\tstruct rte_swx_table_entry *entry;\n+\t\t\tint is_blank_or_comment;\n \n \t\t\tif (fgets(line, 2048, file_default) == NULL)\n \t\t\t\tbreak;\n \n \t\t\tentry = rte_swx_ctl_pipeline_table_entry_read(p->ctl,\n \t\t\t\ttable_name,\n-\t\t\t\tline);\n+\t\t\t\tline,\n+\t\t\t\t&is_blank_or_comment);\n \t\t\tif (!entry) {\n+\t\t\t\tif (is_blank_or_comment)\n+\t\t\t\t\tcontinue;\n+\n \t\t\t\tsnprintf(out, out_size, MSG_FILE_ERR,\n \t\t\t\t\tfile_name_default, line_id);\n \t\t\t\tgoto error;\ndiff --git a/lib/librte_pipeline/rte_swx_ctl.c b/lib/librte_pipeline/rte_swx_ctl.c\nindex 3dfbc4aec..480e34238 100644\n--- a/lib/librte_pipeline/rte_swx_ctl.c\n+++ b/lib/librte_pipeline/rte_swx_ctl.c\n@@ -1333,19 +1333,32 @@ rte_swx_ctl_pipeline_abort(struct rte_swx_ctl_pipeline *ctl)\n \t\ttable_abort(ctl, i);\n }\n \n+static int\n+token_is_comment(const char *token)\n+{\n+\tif ((token[0] == '#') ||\n+\t    (token[0] == ';') ||\n+\t    ((token[0] == '/') && (token[1] == '/')))\n+\t\treturn 1; /* TRUE. */\n+\n+\treturn 0; /* FALSE. */\n+}\n+\n #define RTE_SWX_CTL_ENTRY_TOKENS_MAX 256\n \n struct rte_swx_table_entry *\n rte_swx_ctl_pipeline_table_entry_read(struct rte_swx_ctl_pipeline *ctl,\n \t\t\t\t      const char *table_name,\n-\t\t\t\t      const char *string)\n+\t\t\t\t      const char *string,\n+\t\t\t\t      int *is_blank_or_comment)\n {\n-\tchar *tokens[RTE_SWX_CTL_ENTRY_TOKENS_MAX];\n+\tchar *token_array[RTE_SWX_CTL_ENTRY_TOKENS_MAX], **tokens;\n \tstruct table *table;\n \tstruct action *action;\n \tstruct rte_swx_table_entry *entry = NULL;\n \tchar *s0 = NULL, *s;\n \tuint32_t n_tokens = 0, arg_offset = 0, i;\n+\tint blank_or_comment = 0;\n \n \t/* Check input arguments. */\n \tif (!ctl)\n@@ -1375,37 +1388,66 @@ rte_swx_ctl_pipeline_table_entry_read(struct rte_swx_ctl_pipeline *ctl,\n \t\tchar *token;\n \n \t\ttoken = strtok_r(s, \" \\f\\n\\r\\t\\v\", &s);\n-\t\tif (!token)\n+\t\tif (!token || token_is_comment(token))\n \t\t\tbreak;\n \n \t\tif (n_tokens >= RTE_SWX_CTL_ENTRY_TOKENS_MAX)\n \t\t\tgoto error;\n \n-\t\ttokens[n_tokens] = token;\n+\t\ttoken_array[n_tokens] = token;\n \t\tn_tokens++;\n \t}\n \n-\tif ((n_tokens < 3 + table->info.n_match_fields) ||\n-\t    strcmp(tokens[0], \"match\") ||\n-\t    strcmp(tokens[1 + table->info.n_match_fields], \"action\"))\n-\t\tgoto error;\n-\n-\taction = action_find(ctl, tokens[2 + table->info.n_match_fields]);\n-\tif (!action)\n+\tif (!n_tokens) {\n+\t\tblank_or_comment = 1;\n \t\tgoto error;\n+\t}\n \n-\tif (n_tokens != 3 + table->info.n_match_fields +\n-\t    action->info.n_args * 2)\n-\t\tgoto error;\n+\ttokens = token_array;\n \n \t/*\n \t * Match.\n \t */\n+\tif (n_tokens && strcmp(tokens[0], \"match\"))\n+\t\tgoto action;\n+\n+\tif (n_tokens < 1 + table->info.n_match_fields)\n+\t\tgoto error;\n+\n \tfor (i = 0; i < table->info.n_match_fields; i++) {\n \t\tstruct rte_swx_ctl_table_match_field_info *mf = &table->mf[i];\n-\t\tchar *mf_val = tokens[1 + i];\n-\t\tuint64_t val;\n+\t\tchar *mf_val = tokens[1 + i], *mf_mask = NULL;\n+\t\tuint64_t val, mask = UINT64_MAX;\n+\t\tuint32_t offset = (mf->offset - table->mf[0].offset) / 8;\n+\n+\t\t/*\n+\t\t * Mask.\n+\t\t */\n+\t\tmf_mask = strchr(mf_val, '/');\n+\t\tif (mf_mask) {\n+\t\t\t*mf_mask = 0;\n+\t\t\tmf_mask++;\n+\n+\t\t\t/* Parse. */\n+\t\t\tmask = strtoull(mf_mask, &mf_mask, 0);\n+\t\t\tif (mf_mask[0])\n+\t\t\t\tgoto error;\n+\n+\t\t\t/* Endianness conversion. */\n+\t\t\tif (mf->is_header)\n+\t\t\t\tmask = field_hton(mask, mf->n_bits);\n+\t\t}\n+\n+\t\t\t/* Copy to entry. */\n+\t\t\tif (entry->key_mask)\n+\t\t\t\tmemcpy(&entry->key_mask[offset],\n+\t\t\t\t       (uint8_t *)&mask,\n+\t\t\t\t       mf->n_bits / 8);\n \n+\t\t/*\n+\t\t * Value.\n+\t\t */\n+\t\t/* Parse. */\n \t\tval = strtoull(mf_val, &mf_val, 0);\n \t\tif (mf_val[0])\n \t\t\tgoto error;\n@@ -1414,17 +1456,32 @@ rte_swx_ctl_pipeline_table_entry_read(struct rte_swx_ctl_pipeline *ctl,\n \t\tif (mf->is_header)\n \t\t\tval = field_hton(val, mf->n_bits);\n \n-\t\t/* Copy key and key_mask to entry. */\n-\t\tmemcpy(&entry->key[(mf->offset - table->mf[0].offset) / 8],\n+\t\t/* Copy to entry. */\n+\t\tmemcpy(&entry->key[offset],\n \t\t       (uint8_t *)&val,\n \t\t       mf->n_bits / 8);\n-\n-\t\t/* TBD Set entry->key_mask for wildcard and LPM tables. */\n \t}\n \n+\ttokens += 1 + table->info.n_match_fields;\n+\tn_tokens -= 1 + table->info.n_match_fields;\n+\n \t/*\n \t * Action.\n \t */\n+action:\n+\tif (n_tokens && strcmp(tokens[0], \"action\"))\n+\t\tgoto other;\n+\n+\tif (n_tokens < 2)\n+\t\tgoto error;\n+\n+\taction = action_find(ctl, tokens[1]);\n+\tif (!action)\n+\t\tgoto error;\n+\n+\tif (n_tokens < 2 + action->info.n_args * 2)\n+\t\tgoto error;\n+\n \t/* action_id. */\n \tentry->action_id = action - ctl->actions;\n \n@@ -1435,8 +1492,8 @@ rte_swx_ctl_pipeline_table_entry_read(struct rte_swx_ctl_pipeline *ctl,\n \t\tuint64_t val;\n \t\tint is_nbo = 0;\n \n-\t\targ_name = tokens[3 + table->info.n_match_fields + i * 2];\n-\t\targ_val = tokens[3 + table->info.n_match_fields + i * 2 + 1];\n+\t\targ_name = tokens[2 + i * 2];\n+\t\targ_val = tokens[2 + i * 2 + 1];\n \n \t\tif (strcmp(arg_name, arg->name) ||\n \t\t    (strlen(arg_val) < 4) ||\n@@ -1467,15 +1524,50 @@ rte_swx_ctl_pipeline_table_entry_read(struct rte_swx_ctl_pipeline *ctl,\n \t\targ_offset += arg->n_bits / 8;\n \t}\n \n+\ttokens += 2 + action->info.n_args * 2;\n+\tn_tokens -= 2 + action->info.n_args * 2;\n+\n+other:\n+\tif (n_tokens)\n+\t\tgoto error;\n+\n \tfree(s0);\n \treturn entry;\n \n error:\n \ttable_entry_free(entry);\n \tfree(s0);\n+\tif (is_blank_or_comment)\n+\t\t*is_blank_or_comment = blank_or_comment;\n \treturn NULL;\n }\n \n+static void\n+table_entry_printf(FILE *f,\n+\t\t   struct rte_swx_ctl_pipeline *ctl,\n+\t\t   struct table *table,\n+\t\t   struct rte_swx_table_entry *entry)\n+{\n+\tstruct action *action = &ctl->actions[entry->action_id];\n+\tuint32_t i;\n+\n+\tfprintf(f, \"match \");\n+\tfor (i = 0; i < table->params.key_size; i++)\n+\t\tfprintf(f, \"%02x\", entry->key[i]);\n+\n+\tif (entry->key_mask) {\n+\t\tfprintf(f, \"/\");\n+\t\tfor (i = 0; i < table->params.key_size; i++)\n+\t\t\tfprintf(f, \"%02x\", entry->key_mask[i]);\n+\t}\n+\n+\tfprintf(f, \" action %s \", action->info.name);\n+\tfor (i = 0; i < action->data_size; i++)\n+\t\tfprintf(f, \"%02x\", entry->action_data[i]);\n+\n+\tfprintf(f, \"\\n\");\n+}\n+\n int\n rte_swx_ctl_pipeline_table_fprintf(FILE *f,\n \t\t\t\t   struct rte_swx_ctl_pipeline *ctl,\n@@ -1506,47 +1598,17 @@ rte_swx_ctl_pipeline_table_fprintf(FILE *f,\n \n \t/* Table entries. */\n \tTAILQ_FOREACH(entry, &table->entries, node) {\n-\t\tstruct action *action = &ctl->actions[entry->action_id];\n-\n-\t\tfprintf(f, \"match \");\n-\t\tfor (i = 0; i < table->params.key_size; i++)\n-\t\t\tfprintf(f, \"%02x\", entry->key[i]);\n-\n-\t\tfprintf(f, \" action %s \", action->info.name);\n-\t\tfor (i = 0; i < action->data_size; i++)\n-\t\t\tfprintf(f, \"%02x\", entry->action_data[i]);\n-\n-\t\tfprintf(f, \"\\n\");\n+\t\ttable_entry_printf(f, ctl, table, entry);\n \t\tn_entries++;\n \t}\n \n \tTAILQ_FOREACH(entry, &table->pending_modify0, node) {\n-\t\tstruct action *action = &ctl->actions[entry->action_id];\n-\n-\t\tfprintf(f, \"match \");\n-\t\tfor (i = 0; i < table->params.key_size; i++)\n-\t\t\tfprintf(f, \"%02x\", entry->key[i]);\n-\n-\t\tfprintf(f, \" action %s \", action->info.name);\n-\t\tfor (i = 0; i < action->data_size; i++)\n-\t\t\tfprintf(f, \"%02x\", entry->action_data[i]);\n-\n-\t\tfprintf(f, \"\\n\");\n+\t\ttable_entry_printf(f, ctl, table, entry);\n \t\tn_entries++;\n \t}\n \n \tTAILQ_FOREACH(entry, &table->pending_delete, node) {\n-\t\tstruct action *action = &ctl->actions[entry->action_id];\n-\n-\t\tfprintf(f, \"match \");\n-\t\tfor (i = 0; i < table->params.key_size; i++)\n-\t\t\tfprintf(f, \"%02x\", entry->key[i]);\n-\n-\t\tfprintf(f, \" action %s \", action->info.name);\n-\t\tfor (i = 0; i < action->data_size; i++)\n-\t\t\tfprintf(f, \"%02x\", entry->action_data[i]);\n-\n-\t\tfprintf(f, \"\\n\");\n+\t\ttable_entry_printf(f, ctl, table, entry);\n \t\tn_entries++;\n \t}\n \ndiff --git a/lib/librte_pipeline/rte_swx_ctl.h b/lib/librte_pipeline/rte_swx_ctl.h\nindex 32815b69e..530671db1 100644\n--- a/lib/librte_pipeline/rte_swx_ctl.h\n+++ b/lib/librte_pipeline/rte_swx_ctl.h\n@@ -521,6 +521,10 @@ rte_swx_ctl_pipeline_abort(struct rte_swx_ctl_pipeline *ctl);\n  *   Table name.\n  * @param[in] string\n  *   String containing the table entry.\n+ * @param[out] is_blank_or_comment\n+ *   On error, this argument provides an indication of whether *string* contains\n+ *   an invalid table entry (set to zero) or a blank or comment line that should\n+ *   typically be ignored (set to a non-zero value).\n  * @return\n  *   0 on success or the following error codes otherwise:\n  *   -EINVAL: Invalid argument.\n@@ -529,7 +533,8 @@ __rte_experimental\n struct rte_swx_table_entry *\n rte_swx_ctl_pipeline_table_entry_read(struct rte_swx_ctl_pipeline *ctl,\n \t\t\t\t      const char *table_name,\n-\t\t\t\t      const char *string);\n+\t\t\t\t      const char *string,\n+\t\t\t\t      int *is_blank_or_comment);\n \n /**\n  * Pipeline table print to file\n",
    "prefixes": [
        "2/5"
    ]
}