get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 93410,
    "url": "https://patches.dpdk.org/api/patches/93410/?format=api",
    "web_url": "https://patches.dpdk.org/project/dpdk/patch/20210524114833.4056-4-ivan.malov@oktetlabs.ru/",
    "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": "<20210524114833.4056-4-ivan.malov@oktetlabs.ru>",
    "list_archive_url": "https://inbox.dpdk.org/dev/20210524114833.4056-4-ivan.malov@oktetlabs.ru",
    "date": "2021-05-24T11:48:33",
    "name": "[v4,3/3] net/sfc: support matching on VLAN presence in transfer rules",
    "commit_ref": null,
    "pull_url": null,
    "state": "accepted",
    "archived": true,
    "hash": "fc5d7f86b36bb4c24f5ca3ed47b19f73106c2dda",
    "submitter": {
        "id": 869,
        "url": "https://patches.dpdk.org/api/people/869/?format=api",
        "name": "Ivan Malov",
        "email": "Ivan.Malov@oktetlabs.ru"
    },
    "delegate": {
        "id": 24651,
        "url": "https://patches.dpdk.org/api/users/24651/?format=api",
        "username": "dmarchand",
        "first_name": "David",
        "last_name": "Marchand",
        "email": "david.marchand@redhat.com"
    },
    "mbox": "https://patches.dpdk.org/project/dpdk/patch/20210524114833.4056-4-ivan.malov@oktetlabs.ru/mbox/",
    "series": [
        {
            "id": 17102,
            "url": "https://patches.dpdk.org/api/series/17102/?format=api",
            "web_url": "https://patches.dpdk.org/project/dpdk/list/?series=17102",
            "date": "2021-05-24T11:48:30",
            "name": "Match On VLAN Presence In Transfer Flows",
            "version": 4,
            "mbox": "https://patches.dpdk.org/series/17102/mbox/"
        }
    ],
    "comments": "https://patches.dpdk.org/api/patches/93410/comments/",
    "check": "fail",
    "checks": "https://patches.dpdk.org/api/patches/93410/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 3444EA0547;\n\tMon, 24 May 2021 13:49:18 +0200 (CEST)",
            "from [217.70.189.124] (localhost [127.0.0.1])\n\tby mails.dpdk.org (Postfix) with ESMTP id A12FD4112B;\n\tMon, 24 May 2021 13:49:02 +0200 (CEST)",
            "from shelob.oktetlabs.ru (shelob.oktetlabs.ru [91.220.146.113])\n by mails.dpdk.org (Postfix) with ESMTP id BD13D41135\n for <dev@dpdk.org>; Mon, 24 May 2021 13:48:59 +0200 (CEST)",
            "from localhost.localdomain (unknown [5.144.120.251])\n (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest\n SHA256)\n (No client certificate requested)\n by shelob.oktetlabs.ru (Postfix) with ESMTPSA id 7A35B7F4F8;\n Mon, 24 May 2021 14:48:59 +0300 (MSK)"
        ],
        "DKIM-Filter": "OpenDKIM Filter v2.11.0 shelob.oktetlabs.ru 7A35B7F4F8",
        "DKIM-Signature": "v=1; a=rsa-sha256; c=simple/simple; d=oktetlabs.ru;\n s=default; t=1621856939;\n bh=nulN7ys9bExBpYf3RVAMl5Wa5tKWVHVfaPFDv2UKki4=;\n h=From:To:Cc:Subject:Date:In-Reply-To:References;\n b=ACUQl9Sk9wEa2Sw7jw5VJXdsl9BX4K1YR9qIkD3aSsOhO4J56enmxexZTx+XAI1t2\n 7Pjn1ED7RIxjEqojfHC1/Lcdg/ojFMoos/6Q/2TyyjBm+vob0WkqyVYXW/vEzaJjf3\n NTjLOF9/U0mzbbF91Mb2tUSjHqCYsRQbEiWB7eHs=",
        "From": "Ivan Malov <ivan.malov@oktetlabs.ru>",
        "To": "dev@dpdk.org",
        "Cc": "Ray Kinsella <mdr@ashroe.eu>, Ferruh Yigit <ferruh.yigit@intel.com>,\n Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>,\n Andy Moreton <amoreton@xilinx.com>",
        "Date": "Mon, 24 May 2021 14:48:33 +0300",
        "Message-Id": "<20210524114833.4056-4-ivan.malov@oktetlabs.ru>",
        "X-Mailer": "git-send-email 2.20.1",
        "In-Reply-To": "<20210524114833.4056-1-ivan.malov@oktetlabs.ru>",
        "References": "<20210428094926.22185-1-ivan.malov@oktetlabs.ru>\n <20210524114833.4056-1-ivan.malov@oktetlabs.ru>",
        "MIME-Version": "1.0",
        "Content-Transfer-Encoding": "8bit",
        "Subject": "[dpdk-dev] [PATCH v4 3/3] net/sfc: support matching on VLAN\n presence in transfer rules",
        "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": "Take into account VLAN presence fields in items ETH and VLAN.\n\nProvided that the item ETH does not match on the EtherType,\nthe pattern behaviour will be as follows:\n\n- ETH (mask->has_vlan = 0) | IPv4        = match both tagged and untagged;\n- ETH (mask->has_vlan = 1) | IPv4        = match as per spec->has_vlan;\n- ETH (mask->has_vlan = 0) | VLAN | IPv4 = match only tagged.\n\nSimilar logic applies to double tagging.\n\nSigned-off-by: Ivan Malov <ivan.malov@oktetlabs.ru>\nReviewed-by: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>\nReviewed-by: Andy Moreton <amoreton@xilinx.com>\n---\n drivers/net/sfc/sfc_mae.c | 124 ++++++++++++++++++++++++++++++++------\n drivers/net/sfc/sfc_mae.h |  19 +++++-\n 2 files changed, 123 insertions(+), 20 deletions(-)",
    "diff": "diff --git a/drivers/net/sfc/sfc_mae.c b/drivers/net/sfc/sfc_mae.c\nindex a2c0aa143..33bff275c 100644\n--- a/drivers/net/sfc/sfc_mae.c\n+++ b/drivers/net/sfc/sfc_mae.c\n@@ -728,6 +728,7 @@ sfc_mae_rule_process_pattern_data(struct sfc_mae_parse_ctx *ctx,\n \t\tRTE_BE16(RTE_ETHER_TYPE_QINQ2),\n \t\tRTE_BE16(RTE_ETHER_TYPE_QINQ3),\n \t};\n+\tbool enforce_tag_presence[SFC_MAE_MATCH_VLAN_MAX_NTAGS] = {0};\n \tunsigned int nb_supported_tpids = RTE_DIM(supported_tpids);\n \tunsigned int ethertype_idx;\n \tconst uint8_t *valuep;\n@@ -753,6 +754,22 @@ sfc_mae_rule_process_pattern_data(struct sfc_mae_parse_ctx *ctx,\n \t     ethertype_idx < pdata->nb_vlan_tags; ++ethertype_idx) {\n \t\tunsigned int tpid_idx;\n \n+\t\t/*\n+\t\t * This loop can have only two iterations. On the second one,\n+\t\t * drop outer tag presence enforcement bit because the inner\n+\t\t * tag presence automatically assumes that for the outer tag.\n+\t\t */\n+\t\tenforce_tag_presence[0] = B_FALSE;\n+\n+\t\tif (ethertypes[ethertype_idx].mask == RTE_BE16(0)) {\n+\t\t\tif (pdata->tci_masks[ethertype_idx] == RTE_BE16(0))\n+\t\t\t\tenforce_tag_presence[ethertype_idx] = B_TRUE;\n+\n+\t\t\t/* No match on this field, and no value check. */\n+\t\t\tnb_supported_tpids = 1;\n+\t\t\tcontinue;\n+\t\t}\n+\n \t\t/* Exact match is supported only. */\n \t\tif (ethertypes[ethertype_idx].mask != RTE_BE16(0xffff)) {\n \t\t\trc = EINVAL;\n@@ -812,6 +829,24 @@ sfc_mae_rule_process_pattern_data(struct sfc_mae_parse_ctx *ctx,\n \t\t}\n \t}\n \n+\tif (enforce_tag_presence[0] || pdata->has_ovlan_mask) {\n+\t\trc = efx_mae_match_spec_bit_set(ctx->match_spec,\n+\t\t\t\t\t\tfremap[EFX_MAE_FIELD_HAS_OVLAN],\n+\t\t\t\t\t\tenforce_tag_presence[0] ||\n+\t\t\t\t\t\tpdata->has_ovlan_value);\n+\t\tif (rc != 0)\n+\t\t\tgoto fail;\n+\t}\n+\n+\tif (enforce_tag_presence[1] || pdata->has_ivlan_mask) {\n+\t\trc = efx_mae_match_spec_bit_set(ctx->match_spec,\n+\t\t\t\t\t\tfremap[EFX_MAE_FIELD_HAS_IVLAN],\n+\t\t\t\t\t\tenforce_tag_presence[1] ||\n+\t\t\t\t\t\tpdata->has_ivlan_value);\n+\t\tif (rc != 0)\n+\t\t\tgoto fail;\n+\t}\n+\n \tvaluep = (const uint8_t *)&pdata->l3_next_proto_value;\n \tmaskp = (const uint8_t *)&pdata->l3_next_proto_mask;\n \trc = efx_mae_match_spec_field_set(ctx->match_spec,\n@@ -1154,6 +1189,7 @@ sfc_mae_rule_parse_item_eth(const struct rte_flow_item *item,\n \n \tsfc_mae_item_build_supp_mask(flocs_eth, RTE_DIM(flocs_eth),\n \t\t\t\t     &supp_mask, sizeof(supp_mask));\n+\tsupp_mask.has_vlan = 1;\n \n \trc = sfc_flow_parse_init(item,\n \t\t\t\t (const void **)&spec, (const void **)&mask,\n@@ -1172,14 +1208,23 @@ sfc_mae_rule_parse_item_eth(const struct rte_flow_item *item,\n \t\titem_spec = (const struct rte_flow_item_eth *)spec;\n \t\titem_mask = (const struct rte_flow_item_eth *)mask;\n \n+\t\t/*\n+\t\t * Remember various match criteria in the parsing context.\n+\t\t * sfc_mae_rule_process_pattern_data() will consider them\n+\t\t * altogether when the rest of the items have been parsed.\n+\t\t */\n \t\tethertypes[0].value = item_spec->type;\n \t\tethertypes[0].mask = item_mask->type;\n+\t\tif (item_mask->has_vlan) {\n+\t\t\tpdata->has_ovlan_mask = B_TRUE;\n+\t\t\tif (item_spec->has_vlan)\n+\t\t\t\tpdata->has_ovlan_value = B_TRUE;\n+\t\t}\n \t} else {\n \t\t/*\n-\t\t * The specification is empty. This is wrong in the case\n-\t\t * when there are more network patterns in line. Other\n-\t\t * than that, any Ethernet can match. All of that is\n-\t\t * checked at the end of parsing.\n+\t\t * The specification is empty. The overall pattern\n+\t\t * validity will be enforced at the end of parsing.\n+\t\t * See sfc_mae_rule_process_pattern_data().\n \t\t */\n \t\treturn 0;\n \t}\n@@ -1229,6 +1274,16 @@ sfc_mae_rule_parse_item_vlan(const struct rte_flow_item *item,\n {\n \tstruct sfc_mae_parse_ctx *ctx_mae = ctx->mae;\n \tstruct sfc_mae_pattern_data *pdata = &ctx_mae->pattern_data;\n+\tboolean_t *has_vlan_mp_by_nb_tags[SFC_MAE_MATCH_VLAN_MAX_NTAGS] = {\n+\t\t&pdata->has_ovlan_mask,\n+\t\t&pdata->has_ivlan_mask,\n+\t};\n+\tboolean_t *has_vlan_vp_by_nb_tags[SFC_MAE_MATCH_VLAN_MAX_NTAGS] = {\n+\t\t&pdata->has_ovlan_value,\n+\t\t&pdata->has_ivlan_value,\n+\t};\n+\tboolean_t *cur_tag_presence_bit_mp;\n+\tboolean_t *cur_tag_presence_bit_vp;\n \tconst struct sfc_mae_field_locator *flocs;\n \tstruct rte_flow_item_vlan supp_mask;\n \tconst uint8_t *spec = NULL;\n@@ -1244,14 +1299,27 @@ sfc_mae_rule_parse_item_vlan(const struct rte_flow_item *item,\n \t\t\t\t\"Can't match that many VLAN tags\");\n \t}\n \n+\tcur_tag_presence_bit_mp = has_vlan_mp_by_nb_tags[pdata->nb_vlan_tags];\n+\tcur_tag_presence_bit_vp = has_vlan_vp_by_nb_tags[pdata->nb_vlan_tags];\n+\n+\tif (*cur_tag_presence_bit_mp == B_TRUE &&\n+\t    *cur_tag_presence_bit_vp == B_FALSE) {\n+\t\treturn rte_flow_error_set(error, EINVAL,\n+\t\t\t\tRTE_FLOW_ERROR_TYPE_ITEM, item,\n+\t\t\t\t\"The previous item enforces no (more) VLAN, \"\n+\t\t\t\t\"so the current item (VLAN) must not exist\");\n+\t}\n+\n \tnb_flocs = RTE_DIM(flocs_vlan) / SFC_MAE_MATCH_VLAN_MAX_NTAGS;\n \tflocs = flocs_vlan + pdata->nb_vlan_tags * nb_flocs;\n \n-\t/* If parsing fails, this can remain incremented. */\n-\t++pdata->nb_vlan_tags;\n-\n \tsfc_mae_item_build_supp_mask(flocs, nb_flocs,\n \t\t\t\t     &supp_mask, sizeof(supp_mask));\n+\t/*\n+\t * This only means that the field is supported by the driver and libefx.\n+\t * Support on NIC level will be checked when all items have been parsed.\n+\t */\n+\tsupp_mask.has_more_vlan = 1;\n \n \trc = sfc_flow_parse_init(item,\n \t\t\t\t (const void **)&spec, (const void **)&mask,\n@@ -1262,26 +1330,44 @@ sfc_mae_rule_parse_item_vlan(const struct rte_flow_item *item,\n \t\treturn rc;\n \n \tif (spec != NULL) {\n-\t\tstruct sfc_mae_ethertype *ethertypes = pdata->ethertypes;\n+\t\tstruct sfc_mae_ethertype *et = pdata->ethertypes;\n \t\tconst struct rte_flow_item_vlan *item_spec;\n \t\tconst struct rte_flow_item_vlan *item_mask;\n \n \t\titem_spec = (const struct rte_flow_item_vlan *)spec;\n \t\titem_mask = (const struct rte_flow_item_vlan *)mask;\n \n-\t\tethertypes[pdata->nb_vlan_tags].value = item_spec->inner_type;\n-\t\tethertypes[pdata->nb_vlan_tags].mask = item_mask->inner_type;\n-\t} else {\n \t\t/*\n-\t\t * The specification is empty. This is wrong in the case\n-\t\t * when there are more network patterns in line. Other\n-\t\t * than that, any Ethernet can match. All of that is\n-\t\t * checked at the end of parsing.\n+\t\t * Remember various match criteria in the parsing context.\n+\t\t * sfc_mae_rule_process_pattern_data() will consider them\n+\t\t * altogether when the rest of the items have been parsed.\n \t\t */\n-\t\treturn 0;\n+\t\tet[pdata->nb_vlan_tags + 1].value = item_spec->inner_type;\n+\t\tet[pdata->nb_vlan_tags + 1].mask = item_mask->inner_type;\n+\t\tpdata->tci_masks[pdata->nb_vlan_tags] = item_mask->tci;\n+\t\tif (item_mask->has_more_vlan) {\n+\t\t\tif (pdata->nb_vlan_tags ==\n+\t\t\t    SFC_MAE_MATCH_VLAN_MAX_NTAGS) {\n+\t\t\t\treturn rte_flow_error_set(error, ENOTSUP,\n+\t\t\t\t\tRTE_FLOW_ERROR_TYPE_ITEM, item,\n+\t\t\t\t\t\"Can't use 'has_more_vlan' in \"\n+\t\t\t\t\t\"the second item VLAN\");\n+\t\t\t}\n+\t\t\tpdata->has_ivlan_mask = B_TRUE;\n+\t\t\tif (item_spec->has_more_vlan)\n+\t\t\t\tpdata->has_ivlan_value = B_TRUE;\n+\t\t}\n+\n+\t\t/* Convert TCI to MAE representation right now. */\n+\t\trc = sfc_mae_parse_item(flocs, nb_flocs, spec, mask,\n+\t\t\t\t\tctx_mae, error);\n+\t\tif (rc != 0)\n+\t\t\treturn rc;\n \t}\n \n-\treturn sfc_mae_parse_item(flocs, nb_flocs, spec, mask, ctx_mae, error);\n+\t++(pdata->nb_vlan_tags);\n+\n+\treturn 0;\n }\n \n static const struct sfc_mae_field_locator flocs_ipv4[] = {\n@@ -1612,6 +1698,8 @@ static const efx_mae_field_id_t field_ids_no_remap[] = {\n \tFIELD_ID_NO_REMAP(L4_SPORT_BE),\n \tFIELD_ID_NO_REMAP(L4_DPORT_BE),\n \tFIELD_ID_NO_REMAP(TCP_FLAGS_BE),\n+\tFIELD_ID_NO_REMAP(HAS_OVLAN),\n+\tFIELD_ID_NO_REMAP(HAS_IVLAN),\n \n #undef FIELD_ID_NO_REMAP\n };\n@@ -1642,6 +1730,8 @@ static const efx_mae_field_id_t field_ids_remap_to_encap[] = {\n \tFIELD_ID_REMAP_TO_ENCAP(DST_IP6_BE),\n \tFIELD_ID_REMAP_TO_ENCAP(L4_SPORT_BE),\n \tFIELD_ID_REMAP_TO_ENCAP(L4_DPORT_BE),\n+\tFIELD_ID_REMAP_TO_ENCAP(HAS_OVLAN),\n+\tFIELD_ID_REMAP_TO_ENCAP(HAS_IVLAN),\n \n #undef FIELD_ID_REMAP_TO_ENCAP\n };\ndiff --git a/drivers/net/sfc/sfc_mae.h b/drivers/net/sfc/sfc_mae.h\nindex 9740e54e4..0241fe33c 100644\n--- a/drivers/net/sfc/sfc_mae.h\n+++ b/drivers/net/sfc/sfc_mae.h\n@@ -130,12 +130,14 @@ struct sfc_mae_pattern_data {\n \t *\n \t * - If an item ETH is followed by a single item VLAN,\n \t *   the former must have \"type\" set to one of supported\n-\t *   TPID values (0x8100, 0x88a8, 0x9100, 0x9200, 0x9300).\n+\t *   TPID values (0x8100, 0x88a8, 0x9100, 0x9200, 0x9300),\n+\t *   or 0x0000/0x0000.\n \t *\n \t * - If an item ETH is followed by two items VLAN, the\n \t *   item ETH must have \"type\" set to one of supported TPID\n-\t *   values (0x88a8, 0x9100, 0x9200, 0x9300), and the outermost\n-\t *   VLAN item must have \"inner_type\" set to TPID value 0x8100.\n+\t *   values (0x88a8, 0x9100, 0x9200, 0x9300), or 0x0000/0x0000,\n+\t *   and the outermost VLAN item must have \"inner_type\" set\n+\t *   to TPID value 0x8100, or 0x0000/0x0000\n \t *\n \t * - If a L2 item is followed by a L3 one, the former must\n \t *   indicate \"type\" (\"inner_type\") which corresponds to\n@@ -156,6 +158,9 @@ struct sfc_mae_pattern_data {\n \t * VLAN\t(L3 EtherType)\t--> ETHER_TYPE_BE\n \t */\n \tstruct sfc_mae_ethertype\tethertypes[SFC_MAE_L2_MAX_NITEMS];\n+\n+\trte_be16_t\t\t\ttci_masks[SFC_MAE_MATCH_VLAN_MAX_NTAGS];\n+\n \tunsigned int\t\t\tnb_vlan_tags;\n \n \t/**\n@@ -191,6 +196,14 @@ struct sfc_mae_pattern_data {\n \t */\n \tuint8_t\t\t\t\tl3_next_proto_restriction_value;\n \tuint8_t\t\t\t\tl3_next_proto_restriction_mask;\n+\n+\t/* Projected state of EFX_MAE_FIELD_HAS_OVLAN match bit */\n+\tbool\t\t\t\thas_ovlan_value;\n+\tbool\t\t\t\thas_ovlan_mask;\n+\n+\t/* Projected state of EFX_MAE_FIELD_HAS_IVLAN match bit */\n+\tbool\t\t\t\thas_ivlan_value;\n+\tbool\t\t\t\thas_ivlan_mask;\n };\n \n struct sfc_mae_parse_ctx {\n",
    "prefixes": [
        "v4",
        "3/3"
    ]
}