From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from EUR02-AM5-obe.outbound.protection.outlook.com (mail-eopbgr00064.outbound.protection.outlook.com [40.107.0.64]) by dpdk.org (Postfix) with ESMTP id 0335A4F9B for ; Mon, 5 Nov 2018 08:20:47 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=Mellanox.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=7lowDM5CaRDMMHrU/ONzELJK/PVlD3Lg5Zk7sB8YhUc=; b=L94ayeUAp0ba7AzCuzdi1rEoUniwWhp/NxL9P9cAtmzv5eN10d7RFwogO9+JoGhrxzAcgAl4YL30oWQEoGtvrmWmHu68BwKAQji2e4UkLnbvGRRoMB1uNiIw1+6d6eOf025qvn1fpEIsVHn7gIiYOxyqBILENiZnMOOWXSJrTj0= Received: from DB3PR0502MB3980.eurprd05.prod.outlook.com (52.134.72.27) by DB3PR0502MB4076.eurprd05.prod.outlook.com (52.134.66.11) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.1294.30; Mon, 5 Nov 2018 07:20:45 +0000 Received: from DB3PR0502MB3980.eurprd05.prod.outlook.com ([fe80::58e7:97d8:f9c1:4323]) by DB3PR0502MB3980.eurprd05.prod.outlook.com ([fe80::58e7:97d8:f9c1:4323%3]) with mapi id 15.20.1294.028; Mon, 5 Nov 2018 07:20:45 +0000 From: Yongseok Koh To: Shahaf Shuler CC: "dev@dpdk.org" , Ori Kam , Yongseok Koh Thread-Topic: [PATCH v2 2/3] net/mlx5: fix Direct Verbs flow tunnel Thread-Index: AQHUdNgRO6HStSTstEiBskO3OlOxZQ== Date: Mon, 5 Nov 2018 07:20:45 +0000 Message-ID: <20181105072032.42374-3-yskoh@mellanox.com> References: <20181102210801.28370-1-yskoh@mellanox.com> <20181105072032.42374-1-yskoh@mellanox.com> In-Reply-To: <20181105072032.42374-1-yskoh@mellanox.com> Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-clientproxiedby: BYAPR07CA0030.namprd07.prod.outlook.com (2603:10b6:a02:bc::43) To DB3PR0502MB3980.eurprd05.prod.outlook.com (2603:10a6:8:10::27) authentication-results: spf=none (sender IP is ) smtp.mailfrom=yskoh@mellanox.com; x-ms-exchange-messagesentrepresentingtype: 1 x-originating-ip: [209.116.155.178] x-ms-publictraffictype: Email x-microsoft-exchange-diagnostics: 1; DB3PR0502MB4076; 6:Q8nWe3ihAZyS46CKVCVxnm4S4ykkBO4IOmiPSJl0sWE6OHs24Ox8/hhOZB8QGWpwDhAjO/ZFooxZlF2gBrxM72bRhT858vdjNCsApuCl4kP/NHXI+sqK3jWkN4i/UZaAC6WfTECG1SHntAMl1qeN+f85ryaoM3MXdbFi1xWPrz6yFeV04JgG2hHRvbIc8GqKkwoRfeVAwJ8wqmwVeWIcnxt65vYCRWaA4f9lewI6Z8cjBS9AqF5PPKLMUsfcI2FX7fKk2vXl91DXR4A/0oTOews7xDAt5UEV7OiFik49gjqcnhX/Ua/OZOkU6hAm5VwViHIgpux6Wd3gtuaHWlTE+ScrXvkNX5twlpefjAl1DmgIi6yWODdhCIucyvQ9sYYdXH1jXI5D8c8OYV2ry8sjxETew85H5cYaObNXK5RR6KQWznk9Zd0TVd2UzOUmZQ8/VAQkvLmZGP4dpl2Cek5Cfw==; 5:mKXKlQSgQYyhEXsWvdHMEh6gsMRT4ORxhFDApJrf0lGoAszNxtcHBB26A9Iz7NdPpj/CJUlyJ+Mj4f6ujDt5pWZCIVSIPURxkWZwgXyrUkdgRitmLfhc9ymG3zde2UB7ZKBPfuW1nPFGah7SNcmFNIjdr6Tgf+Eh4gAY30cD7LM=; 7:GiUqf8APODY5JzgoiyC2i3JFk7EmS4J77Ur1w3qCj9uWZMJt5q7gqPOoWCRsRa7bV6F1qBIzVnbi1516WjRyb+VcCpxy3/vvIT50HS6fSO2QCz8MMP0UwAolRm1bQoHLDbYH77XXRNlVMqiJ5lgmYg== x-ms-office365-filtering-correlation-id: b840c058-d074-4267-6e9d-08d642ef33ca x-ms-office365-filtering-ht: Tenant x-microsoft-antispam: BCL:0; PCL:0; RULEID:(7020095)(4652040)(8989299)(4534185)(4627221)(201703031133081)(201702281549075)(8990200)(5600074)(711020)(4618075)(2017052603328)(7153060)(7193020); SRVR:DB3PR0502MB4076; x-ms-traffictypediagnostic: DB3PR0502MB4076: x-microsoft-antispam-prvs: x-exchange-antispam-report-test: UriScan:; x-ms-exchange-senderadcheck: 1 x-exchange-antispam-report-cfa-test: BCL:0; PCL:0; RULEID:(8211001083)(6040522)(2401047)(5005006)(8121501046)(10201501046)(3002001)(93006095)(93001095)(3231382)(944501410)(52105095)(6055026)(148016)(149066)(150057)(6041310)(201703131423095)(201702281528075)(20161123555045)(201703061421075)(201703061406153)(20161123558120)(20161123564045)(20161123560045)(20161123562045)(201708071742011)(7699051)(76991095); SRVR:DB3PR0502MB4076; BCL:0; PCL:0; RULEID:; SRVR:DB3PR0502MB4076; x-forefront-prvs: 08476BC6EF x-forefront-antispam-report: SFV:NSPM; SFS:(10009020)(346002)(376002)(366004)(396003)(136003)(39860400002)(51234002)(189003)(199004)(66066001)(106356001)(25786009)(446003)(11346002)(97736004)(256004)(14454004)(105586002)(14444005)(68736007)(6512007)(53946003)(2900100001)(2906002)(53936002)(3846002)(6116002)(1076002)(37006003)(6506007)(386003)(52116002)(99286004)(36756003)(4744004)(7736002)(305945005)(6486002)(316002)(6436002)(54906003)(186003)(4326008)(102836004)(86362001)(71190400001)(71200400001)(81166006)(81156014)(486006)(8676002)(6862004)(6636002)(5660300001)(478600001)(107886003)(476003)(2616005)(8936002)(76176011)(26005); DIR:OUT; SFP:1101; SCL:1; SRVR:DB3PR0502MB4076; H:DB3PR0502MB3980.eurprd05.prod.outlook.com; FPR:; SPF:None; LANG:en; PTR:InfoNoRecords; MX:1; A:1; received-spf: None (protection.outlook.com: mellanox.com does not designate permitted sender hosts) x-microsoft-antispam-message-info: FcdE986TdCyTkz3dcQE/0dooLBYBp9GS93U6XyW3g3LJWVCbXlRLX7rBU8VV4CL4d17Jrq0fD5y6ih5Tb1fePHoWWAB26ujcYc58fN82VAvCziNBNoXNpTOc4n7XB5j7lAhaTfAvWqFEg/CuIjtMVlVDRq1kzyzufdLHSnMUaNld6rxUEdawQEy5gQRA5dcbN8s+0b3KB2XFvbiWSiGmQo/HI/bVHHW9LWrnDJibDtBbnYzG25qlvjJwu7dn0A/WmO6+cRgZNDYyBOztMOefX5AkFDdV/9HCDKuxhgal/GbiMkch5j57QWCfJTiJIn8YGEzEhNkHsqt7wxskZbR4EkIGEN5IKzQ02yuUnR4jdCY= spamdiagnosticoutput: 1:99 spamdiagnosticmetadata: NSPM Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 X-OriginatorOrg: Mellanox.com X-MS-Exchange-CrossTenant-Network-Message-Id: b840c058-d074-4267-6e9d-08d642ef33ca X-MS-Exchange-CrossTenant-originalarrivaltime: 05 Nov 2018 07:20:45.6931 (UTC) X-MS-Exchange-CrossTenant-fromentityheader: Hosted X-MS-Exchange-CrossTenant-id: a652971c-7d2e-4d9b-a6a4-d149256f461b X-MS-Exchange-Transport-CrossTenantHeadersStamped: DB3PR0502MB4076 Subject: [dpdk-dev] [PATCH v2 2/3] net/mlx5: fix Direct Verbs flow tunnel X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 05 Nov 2018 07:20:47 -0000 1) Fix layer parsing In translation of tunneled flows, dev_flow->layers must not be used to check tunneled layer as it contains all the layers parsed from flow_drv_prepare(). Checking tunneled layer is needed to distinguish between outer and inner item. This should be based on dynamic parsing. With dev_flow->layers on a tunneled flow, items will always be interpreted as inner as dev_flow->layer already has all the items. Dynamic parsing (item_flags) is added as there's no such code. 2) Refactoring code - flow_dv_create_item() and flow_dv_create_action() are merged into flow_dv_translate() for consistency with Verbs and *_validate(). Fixes: 246636411536 ("net/mlx5: fix flow tunnel handling") Fixes: d02cb0691299 ("net/mlx5: add Direct Verbs translate actions") Fixes: fc2c498ccb94 ("net/mlx5: add Direct Verbs translate items") Cc: orika@mellanox.com Signed-off-by: Yongseok Koh --- drivers/net/mlx5/mlx5_flow_dv.c | 494 +++++++++++++++++++-----------------= ---- 1 file changed, 237 insertions(+), 257 deletions(-) diff --git a/drivers/net/mlx5/mlx5_flow_dv.c b/drivers/net/mlx5/mlx5_flow_d= v.c index 1d5b6bf60a..8b4d5956ba 100644 --- a/drivers/net/mlx5/mlx5_flow_dv.c +++ b/drivers/net/mlx5/mlx5_flow_dv.c @@ -1602,252 +1602,6 @@ flow_dv_translate_item_meta(void *matcher, void *ke= y, } } =20 -/** - * Update the matcher and the value based the selected item. - * - * @param[in, out] matcher - * Flow matcher. - * @param[in, out] key - * Flow matcher value. - * @param[in] item - * Flow pattern to translate. - * @param[in, out] dev_flow - * Pointer to the mlx5_flow. - * @param[in] inner - * Item is inner pattern. - */ -static void -flow_dv_create_item(void *matcher, void *key, - const struct rte_flow_item *item, - struct mlx5_flow *dev_flow, - int inner) -{ - struct mlx5_flow_dv_matcher *tmatcher =3D matcher; - - switch (item->type) { - case RTE_FLOW_ITEM_TYPE_ETH: - flow_dv_translate_item_eth(tmatcher->mask.buf, key, item, - inner); - tmatcher->priority =3D MLX5_PRIORITY_MAP_L2; - break; - case RTE_FLOW_ITEM_TYPE_VLAN: - flow_dv_translate_item_vlan(tmatcher->mask.buf, key, item, - inner); - break; - case RTE_FLOW_ITEM_TYPE_IPV4: - flow_dv_translate_item_ipv4(tmatcher->mask.buf, key, item, - inner); - tmatcher->priority =3D MLX5_PRIORITY_MAP_L3; - dev_flow->dv.hash_fields |=3D - mlx5_flow_hashfields_adjust(dev_flow, inner, - MLX5_IPV4_LAYER_TYPES, - MLX5_IPV4_IBV_RX_HASH); - break; - case RTE_FLOW_ITEM_TYPE_IPV6: - flow_dv_translate_item_ipv6(tmatcher->mask.buf, key, item, - inner); - tmatcher->priority =3D MLX5_PRIORITY_MAP_L3; - dev_flow->dv.hash_fields |=3D - mlx5_flow_hashfields_adjust(dev_flow, inner, - MLX5_IPV6_LAYER_TYPES, - MLX5_IPV6_IBV_RX_HASH); - break; - case RTE_FLOW_ITEM_TYPE_TCP: - flow_dv_translate_item_tcp(tmatcher->mask.buf, key, item, - inner); - tmatcher->priority =3D MLX5_PRIORITY_MAP_L4; - dev_flow->dv.hash_fields |=3D - mlx5_flow_hashfields_adjust(dev_flow, inner, - ETH_RSS_TCP, - (IBV_RX_HASH_SRC_PORT_TCP | - IBV_RX_HASH_DST_PORT_TCP)); - break; - case RTE_FLOW_ITEM_TYPE_UDP: - flow_dv_translate_item_udp(tmatcher->mask.buf, key, item, - inner); - tmatcher->priority =3D MLX5_PRIORITY_MAP_L4; - dev_flow->verbs.hash_fields |=3D - mlx5_flow_hashfields_adjust(dev_flow, inner, - ETH_RSS_UDP, - (IBV_RX_HASH_SRC_PORT_UDP | - IBV_RX_HASH_DST_PORT_UDP)); - break; - case RTE_FLOW_ITEM_TYPE_GRE: - flow_dv_translate_item_gre(tmatcher->mask.buf, key, item, - inner); - break; - case RTE_FLOW_ITEM_TYPE_NVGRE: - flow_dv_translate_item_nvgre(tmatcher->mask.buf, key, item, - inner); - break; - case RTE_FLOW_ITEM_TYPE_VXLAN: - case RTE_FLOW_ITEM_TYPE_VXLAN_GPE: - flow_dv_translate_item_vxlan(tmatcher->mask.buf, key, item, - inner); - break; - case RTE_FLOW_ITEM_TYPE_META: - flow_dv_translate_item_meta(tmatcher->mask.buf, key, item); - break; - default: - break; - } -} - -/** - * Store the requested actions in an array. - * - * @param[in] dev - * Pointer to rte_eth_dev structure. - * @param[in] action - * Flow action to translate. - * @param[in, out] dev_flow - * Pointer to the mlx5_flow. - * @param[in] attr - * Pointer to the flow attributes. - * @param[out] error - * Pointer to the error structure. - * - * @return - * 0 on success, a negative errno value otherwise and rte_errno is set. - */ -static int -flow_dv_create_action(struct rte_eth_dev *dev, - const struct rte_flow_action *action, - struct mlx5_flow *dev_flow, - const struct rte_flow_attr *attr, - struct rte_flow_error *error) -{ - const struct rte_flow_action_queue *queue; - const struct rte_flow_action_rss *rss; - int actions_n =3D dev_flow->dv.actions_n; - struct rte_flow *flow =3D dev_flow->flow; - const struct rte_flow_action *action_ptr =3D action; - const uint8_t *rss_key; - - switch (action->type) { - case RTE_FLOW_ACTION_TYPE_VOID: - break; - case RTE_FLOW_ACTION_TYPE_FLAG: - dev_flow->dv.actions[actions_n].type =3D MLX5DV_FLOW_ACTION_TAG; - dev_flow->dv.actions[actions_n].tag_value =3D - mlx5_flow_mark_set(MLX5_FLOW_MARK_DEFAULT); - actions_n++; - flow->actions |=3D MLX5_FLOW_ACTION_FLAG; - break; - case RTE_FLOW_ACTION_TYPE_MARK: - dev_flow->dv.actions[actions_n].type =3D MLX5DV_FLOW_ACTION_TAG; - dev_flow->dv.actions[actions_n].tag_value =3D - mlx5_flow_mark_set - (((const struct rte_flow_action_mark *) - (action->conf))->id); - flow->actions |=3D MLX5_FLOW_ACTION_MARK; - actions_n++; - break; - case RTE_FLOW_ACTION_TYPE_DROP: - dev_flow->dv.actions[actions_n].type =3D MLX5DV_FLOW_ACTION_DROP; - flow->actions |=3D MLX5_FLOW_ACTION_DROP; - break; - case RTE_FLOW_ACTION_TYPE_QUEUE: - queue =3D action->conf; - flow->rss.queue_num =3D 1; - (*flow->queue)[0] =3D queue->index; - flow->actions |=3D MLX5_FLOW_ACTION_QUEUE; - break; - case RTE_FLOW_ACTION_TYPE_RSS: - rss =3D action->conf; - if (flow->queue) - memcpy((*flow->queue), rss->queue, - rss->queue_num * sizeof(uint16_t)); - flow->rss.queue_num =3D rss->queue_num; - /* NULL RSS key indicates default RSS key. */ - rss_key =3D !rss->key ? rss_hash_default_key : rss->key; - memcpy(flow->key, rss_key, MLX5_RSS_HASH_KEY_LEN); - /* RSS type 0 indicates default RSS type ETH_RSS_IP. */ - flow->rss.types =3D !rss->types ? ETH_RSS_IP : rss->types; - flow->rss.level =3D rss->level; - /* Added to array only in apply since we need the QP */ - flow->actions |=3D MLX5_FLOW_ACTION_RSS; - break; - case RTE_FLOW_ACTION_TYPE_VXLAN_ENCAP: - case RTE_FLOW_ACTION_TYPE_NVGRE_ENCAP: - if (flow_dv_create_action_l2_encap(dev, action, - dev_flow, error)) - return -rte_errno; - dev_flow->dv.actions[actions_n].type =3D - MLX5DV_FLOW_ACTION_IBV_FLOW_ACTION; - dev_flow->dv.actions[actions_n].action =3D - dev_flow->dv.encap_decap->verbs_action; - flow->actions |=3D action->type =3D=3D - RTE_FLOW_ACTION_TYPE_VXLAN_ENCAP ? - MLX5_FLOW_ACTION_VXLAN_ENCAP : - MLX5_FLOW_ACTION_NVGRE_ENCAP; - actions_n++; - break; - case RTE_FLOW_ACTION_TYPE_VXLAN_DECAP: - case RTE_FLOW_ACTION_TYPE_NVGRE_DECAP: - if (flow_dv_create_action_l2_decap(dev, dev_flow, error)) - return -rte_errno; - dev_flow->dv.actions[actions_n].type =3D - MLX5DV_FLOW_ACTION_IBV_FLOW_ACTION; - dev_flow->dv.actions[actions_n].action =3D - dev_flow->dv.encap_decap->verbs_action; - flow->actions |=3D action->type =3D=3D - RTE_FLOW_ACTION_TYPE_VXLAN_DECAP ? - MLX5_FLOW_ACTION_VXLAN_DECAP : - MLX5_FLOW_ACTION_NVGRE_DECAP; - actions_n++; - break; - case RTE_FLOW_ACTION_TYPE_RAW_ENCAP: - /* Handle encap action with preceding decap */ - if (flow->actions & MLX5_FLOW_ACTION_RAW_DECAP) { - if (flow_dv_create_action_raw_encap(dev, action, - dev_flow, - attr, error)) - return -rte_errno; - dev_flow->dv.actions[actions_n].type =3D - MLX5DV_FLOW_ACTION_IBV_FLOW_ACTION; - dev_flow->dv.actions[actions_n].action =3D - dev_flow->dv.encap_decap->verbs_action; - } else { - /* Handle encap action without preceding decap */ - if (flow_dv_create_action_l2_encap(dev, action, - dev_flow, error)) - return -rte_errno; - dev_flow->dv.actions[actions_n].type =3D - MLX5DV_FLOW_ACTION_IBV_FLOW_ACTION; - dev_flow->dv.actions[actions_n].action =3D - dev_flow->dv.encap_decap->verbs_action; - } - flow->actions |=3D MLX5_FLOW_ACTION_RAW_ENCAP; - actions_n++; - break; - case RTE_FLOW_ACTION_TYPE_RAW_DECAP: - /* Check if this decap action is followed by encap. */ - for (; action_ptr->type !=3D RTE_FLOW_ACTION_TYPE_END && - action_ptr->type !=3D RTE_FLOW_ACTION_TYPE_RAW_ENCAP; - action_ptr++) { - } - /* Handle decap action only if it isn't followed by encap */ - if (action_ptr->type !=3D RTE_FLOW_ACTION_TYPE_RAW_ENCAP) { - if (flow_dv_create_action_l2_decap(dev, dev_flow, - error)) - return -rte_errno; - dev_flow->dv.actions[actions_n].type =3D - MLX5DV_FLOW_ACTION_IBV_FLOW_ACTION; - dev_flow->dv.actions[actions_n].action =3D - dev_flow->dv.encap_decap->verbs_action; - actions_n++; - } - /* If decap is followed by encap, handle it at encap case. */ - flow->actions |=3D MLX5_FLOW_ACTION_RAW_DECAP; - break; - default: - break; - } - dev_flow->dv.actions_n =3D actions_n; - return 0; -} - static uint32_t matcher_zero[MLX5_ST_SZ_DW(fte_match_param)] =3D { 0 }; =20 #define HEADER_IS_ZERO(match_criteria, headers) \ @@ -1989,34 +1743,260 @@ flow_dv_translate(struct rte_eth_dev *dev, struct rte_flow_error *error) { struct priv *priv =3D dev->data->dev_private; + struct rte_flow *flow =3D dev_flow->flow; + uint64_t item_flags =3D 0; + uint64_t action_flags =3D 0; uint64_t priority =3D attr->priority; struct mlx5_flow_dv_matcher matcher =3D { .mask =3D { .size =3D sizeof(matcher.mask.buf), }, }; - void *match_value =3D dev_flow->dv.value.buf; - int tunnel =3D 0; + int actions_n =3D 0; =20 if (priority =3D=3D MLX5_FLOW_PRIO_RSVD) priority =3D priv->config.flow_prio - 1; for (; items->type !=3D RTE_FLOW_ITEM_TYPE_END; items++) { - tunnel =3D !!(dev_flow->layers & MLX5_FLOW_LAYER_TUNNEL); - flow_dv_create_item(&matcher, match_value, items, dev_flow, - tunnel); + int tunnel =3D !!(item_flags & MLX5_FLOW_LAYER_TUNNEL); + void *match_mask =3D matcher.mask.buf; + void *match_value =3D dev_flow->dv.value.buf; + + switch (items->type) { + case RTE_FLOW_ITEM_TYPE_ETH: + flow_dv_translate_item_eth(match_mask, match_value, + items, tunnel); + matcher.priority =3D MLX5_PRIORITY_MAP_L2; + item_flags |=3D tunnel ? MLX5_FLOW_LAYER_INNER_L2 : + MLX5_FLOW_LAYER_OUTER_L2; + break; + case RTE_FLOW_ITEM_TYPE_VLAN: + flow_dv_translate_item_vlan(match_mask, match_value, + items, tunnel); + matcher.priority =3D MLX5_PRIORITY_MAP_L2; + item_flags |=3D tunnel ? (MLX5_FLOW_LAYER_INNER_L2 | + MLX5_FLOW_LAYER_INNER_VLAN) : + (MLX5_FLOW_LAYER_OUTER_L2 | + MLX5_FLOW_LAYER_OUTER_VLAN); + break; + case RTE_FLOW_ITEM_TYPE_IPV4: + flow_dv_translate_item_ipv4(match_mask, match_value, + items, tunnel); + matcher.priority =3D MLX5_PRIORITY_MAP_L3; + dev_flow->dv.hash_fields |=3D + mlx5_flow_hashfields_adjust + (dev_flow, tunnel, + MLX5_IPV4_LAYER_TYPES, + MLX5_IPV4_IBV_RX_HASH); + item_flags |=3D tunnel ? MLX5_FLOW_LAYER_INNER_L3_IPV4 : + MLX5_FLOW_LAYER_OUTER_L3_IPV4; + break; + case RTE_FLOW_ITEM_TYPE_IPV6: + flow_dv_translate_item_ipv6(match_mask, match_value, + items, tunnel); + matcher.priority =3D MLX5_PRIORITY_MAP_L3; + dev_flow->dv.hash_fields |=3D + mlx5_flow_hashfields_adjust + (dev_flow, tunnel, + MLX5_IPV6_LAYER_TYPES, + MLX5_IPV6_IBV_RX_HASH); + item_flags |=3D tunnel ? MLX5_FLOW_LAYER_INNER_L3_IPV6 : + MLX5_FLOW_LAYER_OUTER_L3_IPV6; + break; + case RTE_FLOW_ITEM_TYPE_TCP: + flow_dv_translate_item_tcp(match_mask, match_value, + items, tunnel); + matcher.priority =3D MLX5_PRIORITY_MAP_L4; + dev_flow->dv.hash_fields |=3D + mlx5_flow_hashfields_adjust + (dev_flow, tunnel, ETH_RSS_TCP, + IBV_RX_HASH_SRC_PORT_TCP | + IBV_RX_HASH_DST_PORT_TCP); + item_flags |=3D tunnel ? MLX5_FLOW_LAYER_INNER_L4_TCP : + MLX5_FLOW_LAYER_OUTER_L4_TCP; + break; + case RTE_FLOW_ITEM_TYPE_UDP: + flow_dv_translate_item_udp(match_mask, match_value, + items, tunnel); + matcher.priority =3D MLX5_PRIORITY_MAP_L4; + dev_flow->verbs.hash_fields |=3D + mlx5_flow_hashfields_adjust + (dev_flow, tunnel, ETH_RSS_UDP, + IBV_RX_HASH_SRC_PORT_UDP | + IBV_RX_HASH_DST_PORT_UDP); + item_flags |=3D tunnel ? MLX5_FLOW_LAYER_INNER_L4_UDP : + MLX5_FLOW_LAYER_OUTER_L4_UDP; + break; + case RTE_FLOW_ITEM_TYPE_GRE: + flow_dv_translate_item_gre(match_mask, match_value, + items, tunnel); + item_flags |=3D MLX5_FLOW_LAYER_GRE; + break; + case RTE_FLOW_ITEM_TYPE_NVGRE: + flow_dv_translate_item_nvgre(match_mask, match_value, + items, tunnel); + item_flags |=3D MLX5_FLOW_LAYER_GRE; + break; + case RTE_FLOW_ITEM_TYPE_VXLAN: + flow_dv_translate_item_vxlan(match_mask, match_value, + items, tunnel); + item_flags |=3D MLX5_FLOW_LAYER_VXLAN; + break; + case RTE_FLOW_ITEM_TYPE_VXLAN_GPE: + flow_dv_translate_item_vxlan(match_mask, match_value, + items, tunnel); + item_flags |=3D MLX5_FLOW_LAYER_VXLAN_GPE; + break; + case RTE_FLOW_ITEM_TYPE_META: + flow_dv_translate_item_meta(match_mask, match_value, + items); + item_flags |=3D MLX5_FLOW_ITEM_METADATA; + break; + default: + break; + } } + dev_flow->layers =3D item_flags; + /* Register matcher. */ matcher.crc =3D rte_raw_cksum((const void *)matcher.mask.buf, - matcher.mask.size); - if (priority =3D=3D MLX5_FLOW_PRIO_RSVD) - priority =3D priv->config.flow_prio - 1; + matcher.mask.size); matcher.priority =3D mlx5_flow_adjust_priority(dev, priority, matcher.priority); matcher.egress =3D attr->egress; if (flow_dv_matcher_register(dev, &matcher, dev_flow, error)) return -rte_errno; - for (; actions->type !=3D RTE_FLOW_ACTION_TYPE_END; actions++) - if (flow_dv_create_action(dev, actions, dev_flow, attr, error)) - return -rte_errno; + for (; actions->type !=3D RTE_FLOW_ACTION_TYPE_END; actions++) { + const struct rte_flow_action_queue *queue; + const struct rte_flow_action_rss *rss; + const struct rte_flow_action *action =3D actions; + const uint8_t *rss_key; + + switch (actions->type) { + case RTE_FLOW_ACTION_TYPE_VOID: + break; + case RTE_FLOW_ACTION_TYPE_FLAG: + dev_flow->dv.actions[actions_n].type =3D + MLX5DV_FLOW_ACTION_TAG; + dev_flow->dv.actions[actions_n].tag_value =3D + mlx5_flow_mark_set(MLX5_FLOW_MARK_DEFAULT); + actions_n++; + action_flags |=3D MLX5_FLOW_ACTION_FLAG; + break; + case RTE_FLOW_ACTION_TYPE_MARK: + dev_flow->dv.actions[actions_n].type =3D + MLX5DV_FLOW_ACTION_TAG; + dev_flow->dv.actions[actions_n].tag_value =3D + mlx5_flow_mark_set + (((const struct rte_flow_action_mark *) + (actions->conf))->id); + actions_n++; + action_flags |=3D MLX5_FLOW_ACTION_MARK; + break; + case RTE_FLOW_ACTION_TYPE_DROP: + dev_flow->dv.actions[actions_n].type =3D + MLX5DV_FLOW_ACTION_DROP; + action_flags |=3D MLX5_FLOW_ACTION_DROP; + break; + case RTE_FLOW_ACTION_TYPE_QUEUE: + queue =3D actions->conf; + flow->rss.queue_num =3D 1; + (*flow->queue)[0] =3D queue->index; + action_flags |=3D MLX5_FLOW_ACTION_QUEUE; + break; + case RTE_FLOW_ACTION_TYPE_RSS: + rss =3D actions->conf; + if (flow->queue) + memcpy((*flow->queue), rss->queue, + rss->queue_num * sizeof(uint16_t)); + flow->rss.queue_num =3D rss->queue_num; + /* NULL RSS key indicates default RSS key. */ + rss_key =3D !rss->key ? rss_hash_default_key : rss->key; + memcpy(flow->key, rss_key, MLX5_RSS_HASH_KEY_LEN); + /* RSS type 0 indicates default RSS type ETH_RSS_IP. */ + flow->rss.types =3D !rss->types ? ETH_RSS_IP : rss->types; + flow->rss.level =3D rss->level; + action_flags |=3D MLX5_FLOW_ACTION_RSS; + break; + case RTE_FLOW_ACTION_TYPE_VXLAN_ENCAP: + case RTE_FLOW_ACTION_TYPE_NVGRE_ENCAP: + if (flow_dv_create_action_l2_encap(dev, actions, + dev_flow, error)) + return -rte_errno; + dev_flow->dv.actions[actions_n].type =3D + MLX5DV_FLOW_ACTION_IBV_FLOW_ACTION; + dev_flow->dv.actions[actions_n].action =3D + dev_flow->dv.encap_decap->verbs_action; + actions_n++; + action_flags |=3D actions->type =3D=3D + RTE_FLOW_ACTION_TYPE_VXLAN_ENCAP ? + MLX5_FLOW_ACTION_VXLAN_ENCAP : + MLX5_FLOW_ACTION_NVGRE_ENCAP; + break; + case RTE_FLOW_ACTION_TYPE_VXLAN_DECAP: + case RTE_FLOW_ACTION_TYPE_NVGRE_DECAP: + if (flow_dv_create_action_l2_decap(dev, dev_flow, + error)) + return -rte_errno; + dev_flow->dv.actions[actions_n].type =3D + MLX5DV_FLOW_ACTION_IBV_FLOW_ACTION; + dev_flow->dv.actions[actions_n].action =3D + dev_flow->dv.encap_decap->verbs_action; + actions_n++; + action_flags |=3D actions->type =3D=3D + RTE_FLOW_ACTION_TYPE_VXLAN_DECAP ? + MLX5_FLOW_ACTION_VXLAN_DECAP : + MLX5_FLOW_ACTION_NVGRE_DECAP; + break; + case RTE_FLOW_ACTION_TYPE_RAW_ENCAP: + /* Handle encap with preceding decap. */ + if (action_flags & MLX5_FLOW_ACTION_RAW_DECAP) { + if (flow_dv_create_action_raw_encap + (dev, actions, dev_flow, attr, error)) + return -rte_errno; + dev_flow->dv.actions[actions_n].type =3D + MLX5DV_FLOW_ACTION_IBV_FLOW_ACTION; + dev_flow->dv.actions[actions_n].action =3D + dev_flow->dv.encap_decap->verbs_action; + } else { + /* Handle encap without preceding decap. */ + if (flow_dv_create_action_l2_encap(dev, actions, + dev_flow, + error)) + return -rte_errno; + dev_flow->dv.actions[actions_n].type =3D + MLX5DV_FLOW_ACTION_IBV_FLOW_ACTION; + dev_flow->dv.actions[actions_n].action =3D + dev_flow->dv.encap_decap->verbs_action; + } + actions_n++; + action_flags |=3D MLX5_FLOW_ACTION_RAW_ENCAP; + break; + case RTE_FLOW_ACTION_TYPE_RAW_DECAP: + /* Check if this decap is followed by encap. */ + for (; action->type !=3D RTE_FLOW_ACTION_TYPE_END && + action->type !=3D RTE_FLOW_ACTION_TYPE_RAW_ENCAP; + action++) { + } + /* Handle decap only if it isn't followed by encap. */ + if (action->type !=3D RTE_FLOW_ACTION_TYPE_RAW_ENCAP) { + if (flow_dv_create_action_l2_decap(dev, + dev_flow, + error)) + return -rte_errno; + dev_flow->dv.actions[actions_n].type =3D + MLX5DV_FLOW_ACTION_IBV_FLOW_ACTION; + dev_flow->dv.actions[actions_n].action =3D + dev_flow->dv.encap_decap->verbs_action; + actions_n++; + } + /* If decap is followed by encap, handle it at encap. */ + action_flags |=3D MLX5_FLOW_ACTION_RAW_DECAP; + break; + default: + break; + } + } + dev_flow->dv.actions_n =3D actions_n; + flow->actions =3D action_flags; return 0; } =20 --=20 2.11.0