From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id B46A9A0A0A; Wed, 28 Apr 2021 19:59:47 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 8E05C412C6; Wed, 28 Apr 2021 19:59:38 +0200 (CEST) Received: from NAM02-BL2-obe.outbound.protection.outlook.com (mail-eopbgr750049.outbound.protection.outlook.com [40.107.75.49]) by mails.dpdk.org (Postfix) with ESMTP id D2E1540147 for ; Wed, 28 Apr 2021 19:59:35 +0200 (CEST) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=MjyyLQsVBcdcfolCpOHtMdHrc4B4DM1w0gaLncTw7JJo5Z2uD1WKWGSdWnxPP3qrDe/ONB+UoztSwGfjbmZc5LdBe0fmVEiaebvjz4y1al7OCw6nKx5duhXtq1LZ0BcldhckgWCGaBcTBeyDftQ8VOvZFhCRrewHDKtUDhA0ItL/H2awWSgF4cOFt06Rj+AoUD1NprOSGK9MgPTkHRytecnMFFFxWeiZkxigLtcoi9JPytfeQkdEsB48Av4wWtXUkGEP7MMYJDCXgx46A1yhPCpR+fAQaQrny+240QtJXiJY6FdDL17kNykeQu+RhRCNSF69jEJSPZYIzIfG9re1NA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=2IIIKMkkAnigtUlpsxOxUmDvoeyTiA1my+gvWIjB5B8=; b=Y+bxmpF3mzJxD7Lxo3ij2YXz9CkyOZX5QQT0vXTvOXobR8aZh9o2dGcMNSvCktCmpkSghtOdzbfrK5IXBpWQLC8NYatFaOJaq8YHHnvEOdFG+vTHYpXYAugez8UZogA+XRakSY5B3oBy5UTgY8uNAseRaEuqYhAXbiVyN6ey9nx4dvBnWrFb4ukVb/qgmeO1B3CM8IsUGaWPpkUCZ4PtvFJkffYi+Q0/ZXDiVaE8fEPdRNsTXNDSbEs6WW5eyhQoGjhOeR3JVi6BACzcJY+PD8VIq/wC4LzSOhHAEeGS03W1efY6Tnm1kbHseAIAoahEo8+iYmCqF1uQrM8EQNcpQQ== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 216.228.112.34) smtp.rcpttodomain=dpdk.org smtp.mailfrom=nvidia.com; dmarc=pass (p=none sp=none pct=100) action=none header.from=nvidia.com; dkim=none (message not signed); arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=Nvidia.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=2IIIKMkkAnigtUlpsxOxUmDvoeyTiA1my+gvWIjB5B8=; b=l8XMwVKNGV+VXVM/xtbJzhpyvjvubamWzcWaAQvHfC/DF3mbGhq69iz2/eqMWJ6eJpJSLU02/jDb9hBSCk+LZmSXSWMIaMSDkIyXwATrOOx1gB08BW25v6gcCjlvX8UQOUJDfo0LWmv7s86NK3+xgppahcWN8RDfZ8Gdg6IQCGlAm2yjeYrRaYMMl042Afkp0QccmiHW2iuYPtoUU2yubgSZhHBSq3zRKL7uK5GIdHV/uOJRjkdKD47cAijOZigxfwoIvmYUaBoPP9DNlIVQ0G1qAzepcPG5TT79+MlIbkVuUKCuv8u0boH8kEmffxMl7a7/ixc8lKxifJgTa2zAww== Received: from DM6PR07CA0071.namprd07.prod.outlook.com (2603:10b6:5:74::48) by MWHPR12MB1262.namprd12.prod.outlook.com (2603:10b6:300:12::10) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4065.26; Wed, 28 Apr 2021 17:59:34 +0000 Received: from DM6NAM11FT056.eop-nam11.prod.protection.outlook.com (2603:10b6:5:74:cafe::1) by DM6PR07CA0071.outlook.office365.com (2603:10b6:5:74::48) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4087.27 via Frontend Transport; Wed, 28 Apr 2021 17:59:34 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 216.228.112.34) smtp.mailfrom=nvidia.com; dpdk.org; dkim=none (message not signed) header.d=none;dpdk.org; dmarc=pass action=none header.from=nvidia.com; Received-SPF: Pass (protection.outlook.com: domain of nvidia.com designates 216.228.112.34 as permitted sender) receiver=protection.outlook.com; client-ip=216.228.112.34; helo=mail.nvidia.com; Received: from mail.nvidia.com (216.228.112.34) by DM6NAM11FT056.mail.protection.outlook.com (10.13.173.99) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384) id 15.20.4065.21 via Frontend Transport; Wed, 28 Apr 2021 17:59:33 +0000 Received: from nvidia.com (172.20.145.6) by HQMAIL107.nvidia.com (172.20.187.13) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Wed, 28 Apr 2021 17:59:31 +0000 From: Gregory Etelson To: CC: , , , , Viacheslav Ovsiienko , "Shahaf Shuler" Date: Wed, 28 Apr 2021 20:59:05 +0300 Message-ID: <20210428175906.21387-4-getelson@nvidia.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210428175906.21387-1-getelson@nvidia.com> References: <20210428175906.21387-1-getelson@nvidia.com> MIME-Version: 1.0 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: 8bit X-Originating-IP: [172.20.145.6] X-ClientProxiedBy: HQMAIL105.nvidia.com (172.20.187.12) To HQMAIL107.nvidia.com (172.20.187.13) X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 21466011-daf6-47df-b005-08d90a6f615a X-MS-TrafficTypeDiagnostic: MWHPR12MB1262: X-Microsoft-Antispam-PRVS: X-MS-Oob-TLC-OOBClassifiers: OLM:240; X-MS-Exchange-SenderADCheck: 1 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: yDwn8/D7K87uIhkav6VuLWLlRbvzA/ZiolZB7u5m/vweozSSVNwyXcqHS+bFh5ZqTSDNYFsxVJpcmD/5XhG144P5yB/FPZQj3xbKWGT/mlt0yBv7VHqDYo4whcPzymH00am0TjQzv4qfpX4Pe1XEOlCfiE1sabI0jJNtKm/ghxS7ErDdJaj4eP1JeEsQ+ZqZfHVweOh2EiGaPjzJL8BCS7Hm37x4FdZRdzGc/Xl7i3Ubpba0hN774eTaNh8Rp1A50YpV+52tjsgbGj/JrFVjgxljv95HO0An9bAlEHKIQkWZaBFbUkf+wOFftRd43Gx5UpFHI/bYIL1S+FpvI9/sNnHjIrQEDa+Hf5H6GvRzYbzReB2+n9sDknLWeV6yNY0qjH/JNmAuGBt86ZwyiJ6oaS7fvF4JncSw0Zo1zlvhLDLwCxnIfxzdnp6y+ailyzuMZEgXJ7oNi9z9VoIwgsXT/lBHmxNbyAY9GOGgPbNMGEVazBsSgbo4+c5Pn8pl3ylBbN/hV3ejCQOWDGtPDlFbCedilT4GrTXDxV2GHHQP7UrO9BgHTPocC53oPss2AO2Ot6p9RvWTDC2lO4eOUi+r/o1Zm4XAqsXJGwIo1X0IS/UrNvcsXXjV6jiKcmpki+Jtewc7MOUMxyYK9s+J24LrVj000brSY1v0rDiM4GzO1Bo3D/12jV8QpxjHUU7sxFVB X-Forefront-Antispam-Report: CIP:216.228.112.34; CTRY:US; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:mail.nvidia.com; PTR:schybrid03.nvidia.com; CAT:NONE; SFS:(4636009)(396003)(39860400002)(346002)(376002)(136003)(36840700001)(46966006)(30864003)(55016002)(54906003)(70206006)(82310400003)(7636003)(82740400003)(8936002)(36756003)(83380400001)(5660300002)(70586007)(2616005)(4326008)(36860700001)(2906002)(316002)(6286002)(36906005)(1076003)(186003)(426003)(7696005)(8676002)(86362001)(26005)(16526019)(107886003)(47076005)(356005)(6666004)(6916009)(478600001)(336012)(309714004); DIR:OUT; SFP:1101; X-OriginatorOrg: Nvidia.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 28 Apr 2021 17:59:33.9137 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 21466011-daf6-47df-b005-08d90a6f615a X-MS-Exchange-CrossTenant-Id: 43083d15-7273-40c1-b7db-39efd9ccc17a X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=43083d15-7273-40c1-b7db-39efd9ccc17a; Ip=[216.228.112.34]; Helo=[mail.nvidia.com] X-MS-Exchange-CrossTenant-AuthSource: DM6NAM11FT056.eop-nam11.prod.protection.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: MWHPR12MB1262 Subject: [dpdk-dev] [PATCH 3/4] net/mlx5: support integrity flow item X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" MLX5 PMD supports the following integrity filters for outer and inner network headers: - l3_ok - l4_ok - ipv4_csum_ok - l4_csum_ok `level` values 0 and 1 reference outer headers. `level` > 1 reference inner headers. Flow rule items supplied by application must explicitly specify network headers referred by integrity item. For example: flow create 0 ingress pattern integrity level is 0 value mask l3_ok value spec l3_ok / eth / ipv6 / end … or flow create 0 ingress pattern integrity level is 0 value mask l4_ok value spec 0 / eth / ipv4 proto is udp / end … Signed-off-by: Gregory Etelson Acked-by: Viacheslav Ovsiienko --- drivers/net/mlx5/mlx5_flow.c | 25 ++++ drivers/net/mlx5/mlx5_flow.h | 26 ++++ drivers/net/mlx5/mlx5_flow_dv.c | 258 ++++++++++++++++++++++++++++++++ 3 files changed, 309 insertions(+) diff --git a/drivers/net/mlx5/mlx5_flow.c b/drivers/net/mlx5/mlx5_flow.c index 15ed5ec7a2..db9a251c68 100644 --- a/drivers/net/mlx5/mlx5_flow.c +++ b/drivers/net/mlx5/mlx5_flow.c @@ -8083,6 +8083,31 @@ mlx5_action_handle_flush(struct rte_eth_dev *dev) return ret; } +const struct rte_flow_item * +mlx5_flow_find_tunnel_item(const struct rte_flow_item *item) +{ + for (; item->type != RTE_FLOW_ITEM_TYPE_END; item++) { + switch (item->type) { + default: + break; + case RTE_FLOW_ITEM_TYPE_VXLAN: + case RTE_FLOW_ITEM_TYPE_VXLAN_GPE: + case RTE_FLOW_ITEM_TYPE_GRE: + case RTE_FLOW_ITEM_TYPE_MPLS: + case RTE_FLOW_ITEM_TYPE_NVGRE: + case RTE_FLOW_ITEM_TYPE_GENEVE: + return item; + case RTE_FLOW_ITEM_TYPE_IPV4: + case RTE_FLOW_ITEM_TYPE_IPV6: + if (item[1].type == RTE_FLOW_ITEM_TYPE_IPV4 || + item[1].type == RTE_FLOW_ITEM_TYPE_IPV6) + return item; + break; + } + } + return NULL; +} + #ifndef HAVE_MLX5DV_DR #define MLX5_DOMAIN_SYNC_FLOW ((1 << 0) | (1 << 1)) #else diff --git a/drivers/net/mlx5/mlx5_flow.h b/drivers/net/mlx5/mlx5_flow.h index 56908ae08b..eb7035d259 100644 --- a/drivers/net/mlx5/mlx5_flow.h +++ b/drivers/net/mlx5/mlx5_flow.h @@ -145,6 +145,9 @@ enum mlx5_feature_name { #define MLX5_FLOW_LAYER_GENEVE_OPT (UINT64_C(1) << 32) #define MLX5_FLOW_LAYER_GTP_PSC (UINT64_C(1) << 33) +/* INTEGRITY item bit */ +#define MLX5_FLOW_ITEM_INTEGRITY (UINT64_C(1) << 34) + /* Outer Masks. */ #define MLX5_FLOW_LAYER_OUTER_L3 \ (MLX5_FLOW_LAYER_OUTER_L3_IPV4 | MLX5_FLOW_LAYER_OUTER_L3_IPV6) @@ -1010,6 +1013,20 @@ struct rte_flow { (MLX5_RSS_HASH_IPV6 | IBV_RX_HASH_DST_PORT_TCP) #define MLX5_RSS_HASH_NONE 0ULL +/* + * Define integrity bits supported by the PMD + */ +#define MLX5_DV_PKT_INTEGRITY_MASK \ + (RTE_FLOW_ITEM_INTEGRITY_L3_OK | RTE_FLOW_ITEM_INTEGRITY_L4_OK | \ + RTE_FLOW_ITEM_INTEGRITY_IPV4_CSUM_OK | \ + RTE_FLOW_ITEM_INTEGRITY_L4_CSUM_OK) + +#define MLX5_ETHER_TYPE_FROM_HEADER(_s, _m, _itm, _prt) do { \ + (_prt) = ((const struct _s *)(_itm)->mask)->_m; \ + (_prt) &= ((const struct _s *)(_itm)->spec)->_m; \ + (_prt) = rte_be_to_cpu_16((_prt)); \ +} while (0) + /* array of valid combinations of RX Hash fields for RSS */ static const uint64_t mlx5_rss_hash_fields[] = { MLX5_RSS_HASH_IPV4, @@ -1282,6 +1299,13 @@ mlx5_aso_meter_by_idx(struct mlx5_priv *priv, uint32_t idx) return &pool->mtrs[idx % MLX5_ASO_MTRS_PER_POOL]; } +static __rte_always_inline const struct rte_flow_item * +mlx5_find_end_item(const struct rte_flow_item *item) +{ + for (; item->type != RTE_FLOW_ITEM_TYPE_END; item++); + return item; +} + int mlx5_flow_group_to_table(struct rte_eth_dev *dev, const struct mlx5_flow_tunnel *tunnel, uint32_t group, uint32_t *table, @@ -1433,6 +1457,8 @@ struct mlx5_flow_meter_sub_policy *mlx5_flow_meter_sub_policy_rss_prepare struct mlx5_flow_rss_desc *rss_desc[MLX5_MTR_RTE_COLORS]); int mlx5_flow_dv_discover_counter_offset_support(struct rte_eth_dev *dev); int mlx5_action_handle_flush(struct rte_eth_dev *dev); +const struct rte_flow_item * +mlx5_flow_find_tunnel_item(const struct rte_flow_item *item); void mlx5_release_tunnel_hub(struct mlx5_dev_ctx_shared *sh, uint16_t port_id); int mlx5_alloc_tunnel_hub(struct mlx5_dev_ctx_shared *sh); diff --git a/drivers/net/mlx5/mlx5_flow_dv.c b/drivers/net/mlx5/mlx5_flow_dv.c index d810466242..2d4042e458 100644 --- a/drivers/net/mlx5/mlx5_flow_dv.c +++ b/drivers/net/mlx5/mlx5_flow_dv.c @@ -6230,6 +6230,163 @@ flow_dv_validate_attributes(struct rte_eth_dev *dev, return ret; } +static uint16_t +mlx5_flow_locate_proto_l3(const struct rte_flow_item **head, + const struct rte_flow_item *end) +{ + const struct rte_flow_item *item = *head; + uint16_t l3_protocol; + + for (; item != end; item++) { + switch (item->type) { + default: + break; + case RTE_FLOW_ITEM_TYPE_IPV4: + l3_protocol = RTE_ETHER_TYPE_IPV4; + goto l3_ok; + case RTE_FLOW_ITEM_TYPE_IPV6: + l3_protocol = RTE_ETHER_TYPE_IPV6; + goto l3_ok; + case RTE_FLOW_ITEM_TYPE_ETH: + if (item->mask && item->spec) { + MLX5_ETHER_TYPE_FROM_HEADER(rte_flow_item_eth, + type, item, + l3_protocol); + if (l3_protocol == RTE_ETHER_TYPE_IPV4 || + l3_protocol == RTE_ETHER_TYPE_IPV6) + goto l3_ok; + } + break; + case RTE_FLOW_ITEM_TYPE_VLAN: + if (item->mask && item->spec) { + MLX5_ETHER_TYPE_FROM_HEADER(rte_flow_item_vlan, + inner_type, item, + l3_protocol); + if (l3_protocol == RTE_ETHER_TYPE_IPV4 || + l3_protocol == RTE_ETHER_TYPE_IPV6) + goto l3_ok; + } + break; + } + } + + return 0; + +l3_ok: + *head = item; + return l3_protocol; +} + +static uint8_t +mlx5_flow_locate_proto_l4(const struct rte_flow_item **head, + const struct rte_flow_item *end) +{ + const struct rte_flow_item *item = *head; + uint8_t l4_protocol; + + for (; item != end; item++) { + switch (item->type) { + default: + break; + case RTE_FLOW_ITEM_TYPE_TCP: + l4_protocol = IPPROTO_TCP; + goto l4_ok; + case RTE_FLOW_ITEM_TYPE_UDP: + l4_protocol = IPPROTO_UDP; + goto l4_ok; + case RTE_FLOW_ITEM_TYPE_IPV4: + if (item->mask && item->spec) { + const struct rte_flow_item_ipv4 *mask, *spec; + + mask = (typeof(mask))item->mask; + spec = (typeof(spec))item->spec; + l4_protocol = mask->hdr.next_proto_id & + spec->hdr.next_proto_id; + if (l4_protocol == IPPROTO_TCP || + l4_protocol == IPPROTO_UDP) + goto l4_ok; + } + break; + case RTE_FLOW_ITEM_TYPE_IPV6: + if (item->mask && item->spec) { + const struct rte_flow_item_ipv6 *mask, *spec; + mask = (typeof(mask))item->mask; + spec = (typeof(spec))item->spec; + l4_protocol = mask->hdr.proto & spec->hdr.proto; + if (l4_protocol == IPPROTO_TCP || + l4_protocol == IPPROTO_UDP) + goto l4_ok; + } + break; + } + } + + return 0; + +l4_ok: + *head = item; + return l4_protocol; +} + +static int +flow_dv_validate_item_integrity(struct rte_eth_dev *dev, + const struct rte_flow_item *rule_items, + const struct rte_flow_item *integrity_item, + struct rte_flow_error *error) +{ + struct mlx5_priv *priv = dev->data->dev_private; + const struct rte_flow_item *tunnel_item, *end_item, *item = rule_items; + const struct rte_flow_item_integrity *mask = (typeof(mask)) + integrity_item->mask; + const struct rte_flow_item_integrity *spec = (typeof(spec)) + integrity_item->spec; + uint32_t protocol; + + if (!priv->config.hca_attr.pkt_integrity_match) + return rte_flow_error_set(error, ENOTSUP, + RTE_FLOW_ERROR_TYPE_ITEM, + integrity_item, + "packet integrity integrity_item not supported"); + if (!mask) + mask = &rte_flow_item_integrity_mask; + if (mask->value && ((mask->value & ~MLX5_DV_PKT_INTEGRITY_MASK) != 0)) + return rte_flow_error_set(error, ENOTSUP, + RTE_FLOW_ERROR_TYPE_ITEM, + integrity_item, + "unsupported integrity filter"); + tunnel_item = mlx5_flow_find_tunnel_item(rule_items); + if (spec->level > 1) { + if (!tunnel_item) + return rte_flow_error_set(error, ENOTSUP, + RTE_FLOW_ERROR_TYPE_ITEM, + integrity_item, + "missing tunnel item"); + item = tunnel_item; + end_item = mlx5_find_end_item(tunnel_item); + } else { + end_item = tunnel_item ? tunnel_item : + mlx5_find_end_item(integrity_item); + } + if (mask->l3_ok || mask->ipv4_csum_ok) { + protocol = mlx5_flow_locate_proto_l3(&item, end_item); + if (!protocol) + return rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_ITEM, + integrity_item, + "missing L3 protocol"); + } + if (mask->l4_ok || mask->l4_csum_ok) { + protocol = mlx5_flow_locate_proto_l4(&item, end_item); + if (!protocol) + return rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_ITEM, + integrity_item, + "missing L4 protocol"); + } + + return 0; +} + /** * Internal validation function. For validating both actions and items. * @@ -6321,6 +6478,7 @@ flow_dv_validate(struct rte_eth_dev *dev, const struct rte_flow_attr *attr, .fdb_def_rule = !!priv->fdb_def_rule, }; const struct rte_eth_hairpin_conf *conf; + const struct rte_flow_item *rule_items = items; bool def_policy = false; if (items == NULL) @@ -6644,6 +6802,18 @@ flow_dv_validate(struct rte_eth_dev *dev, const struct rte_flow_attr *attr, return ret; last_item = MLX5_FLOW_LAYER_ECPRI; break; + case RTE_FLOW_ITEM_TYPE_INTEGRITY: + if (item_flags & RTE_FLOW_ITEM_TYPE_INTEGRITY) + return rte_flow_error_set + (error, ENOTSUP, + RTE_FLOW_ERROR_TYPE_ITEM, + NULL, "multiple integrity items not supported"); + ret = flow_dv_validate_item_integrity(dev, rule_items, + items, error); + if (ret < 0) + return ret; + last_item = MLX5_FLOW_ITEM_INTEGRITY; + break; default: return rte_flow_error_set(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ITEM, @@ -11119,6 +11289,90 @@ flow_dv_translate_create_aso_age(struct rte_eth_dev *dev, return age_idx; } +static void +flow_dv_translate_integrity_l4(const struct rte_flow_item_integrity *mask, + const struct rte_flow_item_integrity *value, + void *headers_m, void *headers_v) +{ + if (mask->l4_ok) { + /* application l4_ok filter aggregates all hardware l4 filters + * therefore hw l4_checksum_ok must be implicitly added here. + */ + MLX5_SET(fte_match_set_lyr_2_4, headers_m, l4_checksum_ok, 1); + if (value->l4_ok) { + /* application l4_ok = 1 matches sets both hw flags + * l4_ok and l4_checksum_ok flags to 1. + */ + MLX5_SET(fte_match_set_lyr_2_4, headers_v, + l4_checksum_ok, 1); + MLX5_SET(fte_match_set_lyr_2_4, headers_m, l4_ok, 1); + MLX5_SET(fte_match_set_lyr_2_4, headers_v, l4_ok, 1); + } else { + /* application l4_ok = 0 matches on hw flag + * l4_checksum_ok = 0 only. + */ + MLX5_SET(fte_match_set_lyr_2_4, headers_v, + l4_checksum_ok, 0); + } + } else if (mask->l4_csum_ok) { + MLX5_SET(fte_match_set_lyr_2_4, headers_m, l4_checksum_ok, + mask->l4_csum_ok); + MLX5_SET(fte_match_set_lyr_2_4, headers_v, ipv4_checksum_ok, + mask->ipv4_csum_ok & value->ipv4_csum_ok); + } +} + +static void +flow_dv_translate_integrity_l3(const struct rte_flow_item_integrity *mask, + const struct rte_flow_item_integrity *value, + void *headers_m, void *headers_v) +{ + if (mask->l3_ok) { + MLX5_SET(fte_match_set_lyr_2_4, headers_m, ipv4_checksum_ok, + mask->ipv4_csum_ok); + if (value->l3_ok) { + MLX5_SET(fte_match_set_lyr_2_4, headers_v, + ipv4_checksum_ok, 1); + MLX5_SET(fte_match_set_lyr_2_4, headers_m, l3_ok, 1); + MLX5_SET(fte_match_set_lyr_2_4, headers_v, l3_ok, 1); + } else { + MLX5_SET(fte_match_set_lyr_2_4, headers_v, + ipv4_checksum_ok, 0); + } + } else if (mask->ipv4_csum_ok) { + MLX5_SET(fte_match_set_lyr_2_4, headers_m, ipv4_checksum_ok, + mask->ipv4_csum_ok); + MLX5_SET(fte_match_set_lyr_2_4, headers_v, ipv4_checksum_ok, + value->ipv4_csum_ok); + } +} + +static void +flow_dv_translate_item_integrity(void *matcher, void *key, + const struct rte_flow_item *item) +{ + const struct rte_flow_item_integrity *mask = item->mask; + const struct rte_flow_item_integrity *value = item->spec; + void *headers_m; + void *headers_v; + + if (!value) + return; + if (!mask) + mask = &rte_flow_item_integrity_mask; + if (value->level > 1) { + headers_m = MLX5_ADDR_OF(fte_match_param, matcher, + inner_headers); + headers_v = MLX5_ADDR_OF(fte_match_param, key, inner_headers); + } else { + headers_m = MLX5_ADDR_OF(fte_match_param, matcher, + outer_headers); + headers_v = MLX5_ADDR_OF(fte_match_param, key, outer_headers); + } + flow_dv_translate_integrity_l3(mask, value, headers_m, headers_v); + flow_dv_translate_integrity_l4(mask, value, headers_m, headers_v); +} + /** * Fill the flow with DV spec, lock free * (mutex should be acquired by caller). @@ -12027,6 +12281,10 @@ flow_dv_translate(struct rte_eth_dev *dev, /* No other protocol should follow eCPRI layer. */ last_item = MLX5_FLOW_LAYER_ECPRI; break; + case RTE_FLOW_ITEM_TYPE_INTEGRITY: + flow_dv_translate_item_integrity(match_mask, + match_value, items); + break; default: break; } -- 2.31.1