From patchwork Fri Jun 23 16:58:23 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Artemii Morozov X-Patchwork-Id: 128974 X-Patchwork-Delegate: ferruh.yigit@amd.com Return-Path: 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]) by inbox.dpdk.org (Postfix) with ESMTP id 3A89342D32; Fri, 23 Jun 2023 18:58:36 +0200 (CEST) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id AED0242B7E; Fri, 23 Jun 2023 18:58:32 +0200 (CEST) Received: from agw.arknetworks.am (agw.arknetworks.am [79.141.165.80]) by mails.dpdk.org (Postfix) with ESMTP id C3C0142B71 for ; Fri, 23 Jun 2023 18:58:31 +0200 (CEST) Received: from localhost.localdomain (unknown [37.252.88.53]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by agw.arknetworks.am (Postfix) with ESMTPSA id C0933E12F6; Fri, 23 Jun 2023 20:58:29 +0400 (+04) From: Artemii Morozov To: dev@dpdk.org Cc: Ivan Malov , Viacheslav Galaktionov , Andy Moreton , Andrew Rybchenko , Ferruh Yigit Subject: [PATCH 1/2] common/sfc_efx/base: add MAE IP fragmentation match bits Date: Fri, 23 Jun 2023 20:58:23 +0400 Message-Id: <20230623165824.51908-2-artemii.morozov@arknetworks.am> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230623165824.51908-1-artemii.morozov@arknetworks.am> References: <20230623165824.51908-1-artemii.morozov@arknetworks.am> MIME-Version: 1.0 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 Introduce necessary infrastructure for these bits to be set and validated. Using a combination of these bits IP fragmentation can be configured. Signed-off-by: Artemii Morozov Reviewed-by: Ivan Malov Reviewed-by: Andy Moreton --- drivers/common/sfc_efx/base/efx.h | 4 ++++ drivers/common/sfc_efx/base/efx_mae.c | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/drivers/common/sfc_efx/base/efx.h b/drivers/common/sfc_efx/base/efx.h index 77f855bfb0..efefea717f 100644 --- a/drivers/common/sfc_efx/base/efx.h +++ b/drivers/common/sfc_efx/base/efx.h @@ -4317,6 +4317,10 @@ typedef enum efx_mae_field_id_e { */ EFX_MAE_FIELD_RECIRC_ID, EFX_MAE_FIELD_CT_MARK, + + /* Single bits which can be set by efx_mae_match_spec_bit_set(). */ + EFX_MAE_FIELD_IS_IP_FRAG, + EFX_MAE_FIELD_IP_FIRST_FRAG, EFX_MAE_FIELD_NIDS } efx_mae_field_id_t; diff --git a/drivers/common/sfc_efx/base/efx_mae.c b/drivers/common/sfc_efx/base/efx_mae.c index 9ff887e04b..d36cdc71be 100644 --- a/drivers/common/sfc_efx/base/efx_mae.c +++ b/drivers/common/sfc_efx/base/efx_mae.c @@ -483,6 +483,8 @@ typedef enum efx_mae_field_cap_id_e { EFX_MAE_FIELD_ID_ENC_HAS_IVLAN = MAE_FIELD_ENC_HAS_IVLAN, EFX_MAE_FIELD_ID_RECIRC_ID = MAE_FIELD_RECIRC_ID, EFX_MAE_FIELD_ID_CT_MARK = MAE_FIELD_CT_MARK, + EFX_MAE_FIELD_ID_IS_IP_FRAG = MAE_FIELD_IS_IP_FRAG, + EFX_MAE_FIELD_ID_IP_FIRST_FRAG = MAE_FIELD_IP_FIRST_FRAG, EFX_MAE_FIELD_CAP_NIDS } efx_mae_field_cap_id_t; @@ -668,6 +670,8 @@ static const efx_mae_mv_bit_desc_t __efx_mae_action_rule_mv_bit_desc_set[] = { EFX_MAE_MV_BIT_DESC(HAS_IVLAN), EFX_MAE_MV_BIT_DESC(ENC_HAS_OVLAN), EFX_MAE_MV_BIT_DESC(ENC_HAS_IVLAN), + EFX_MAE_MV_BIT_DESC(IS_IP_FRAG), + EFX_MAE_MV_BIT_DESC(IP_FIRST_FRAG), #undef EFX_MAE_MV_BIT_DESC }; From patchwork Fri Jun 23 16:58:24 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Artemii Morozov X-Patchwork-Id: 128975 X-Patchwork-Delegate: ferruh.yigit@amd.com Return-Path: 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]) by inbox.dpdk.org (Postfix) with ESMTP id 7952B42D32; Fri, 23 Jun 2023 18:58:42 +0200 (CEST) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id DB2B542C24; Fri, 23 Jun 2023 18:58:34 +0200 (CEST) Received: from agw.arknetworks.am (agw.arknetworks.am [79.141.165.80]) by mails.dpdk.org (Postfix) with ESMTP id A8C6142BDA for ; Fri, 23 Jun 2023 18:58:33 +0200 (CEST) Received: from localhost.localdomain (unknown [37.252.88.53]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by agw.arknetworks.am (Postfix) with ESMTPSA id 0A4C6E12F7; Fri, 23 Jun 2023 20:58:31 +0400 (+04) From: Artemii Morozov To: dev@dpdk.org Cc: Ivan Malov , Viacheslav Galaktionov , Andy Moreton , Andrew Rybchenko , Ferruh Yigit Subject: [PATCH 2/2] net/sfc: support IPv4 fragment matching in transfer rules Date: Fri, 23 Jun 2023 20:58:24 +0400 Message-Id: <20230623165824.51908-3-artemii.morozov@arknetworks.am> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230623165824.51908-1-artemii.morozov@arknetworks.am> References: <20230623165824.51908-1-artemii.morozov@arknetworks.am> MIME-Version: 1.0 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 This patch adds the support for IPv4 fragmented packets, but with some limitations: for non-zero fragment offset an exact match is not allowed, but ranges are allowed. Signed-off-by: Artemii Morozov Reviewed-by: Viacheslav Galaktionov Reviewed-by: Andy Moreton --- drivers/net/sfc/sfc_mae.c | 110 +++++++++++++++++++++++++++++++++++++- drivers/net/sfc/sfc_mae.h | 4 ++ 2 files changed, 113 insertions(+), 1 deletion(-) diff --git a/drivers/net/sfc/sfc_mae.c b/drivers/net/sfc/sfc_mae.c index a3131c244d..d1503f39b4 100644 --- a/drivers/net/sfc/sfc_mae.c +++ b/drivers/net/sfc/sfc_mae.c @@ -1700,6 +1700,80 @@ sfc_mae_rule_process_pattern_data(struct sfc_mae_parse_ctx *ctx, if (rc != 0) goto fail; + if (pdata->l3_frag_ofst_mask != 0) { + const rte_be16_t hdr_mask = RTE_BE16(RTE_IPV4_HDR_OFFSET_MASK); + rte_be16_t value; + rte_be16_t last; + boolean_t first_frag; + boolean_t is_ip_frag; + boolean_t any_frag; + + if (pdata->l3_frag_ofst_mask & RTE_BE16(RTE_IPV4_HDR_DF_FLAG)) { + sfc_err(ctx->sa, "Don't fragment flag is not supported."); + rc = ENOTSUP; + goto fail; + } + + if ((pdata->l3_frag_ofst_mask & hdr_mask) != hdr_mask) { + sfc_err(ctx->sa, "Invalid value for fragment offset mask."); + rc = EINVAL; + goto fail; + } + + value = pdata->l3_frag_ofst_mask & pdata->l3_frag_ofst_value; + last = pdata->l3_frag_ofst_mask & pdata->l3_frag_ofst_last; + + /* + * value: last: matches: + * 0 0 Non-fragmented packet + * 1 0x1fff Non-first fragment + * 1 0x1fff+MF Any fragment + * MF 0 First fragment + */ + if (last == 0 && + (pdata->l3_frag_ofst_value & hdr_mask) != 0) { + sfc_err(ctx->sa, + "Exact matching is prohibited for non-zero offsets, but ranges are allowed."); + rc = EINVAL; + goto fail; + } + + if (value == 0 && last == 0) { + is_ip_frag = false; + any_frag = true; + } else if (value == RTE_BE16(1) && (last & hdr_mask) == hdr_mask) { + if (last & RTE_BE16(RTE_IPV4_HDR_MF_FLAG)) { + is_ip_frag = true; + any_frag = true; + } else { + is_ip_frag = true; + any_frag = false; + first_frag = false; + } + } else if (value == RTE_BE16(RTE_IPV4_HDR_MF_FLAG) && last == 0) { + is_ip_frag = true; + any_frag = false; + first_frag = true; + } else { + sfc_err(ctx->sa, "Invalid value for fragment offset."); + rc = EINVAL; + goto fail; + } + + rc = efx_mae_match_spec_bit_set(ctx->match_spec, + fremap[EFX_MAE_FIELD_IS_IP_FRAG], is_ip_frag); + if (rc != 0) + goto fail; + + if (!any_frag) { + rc = efx_mae_match_spec_bit_set(ctx->match_spec, + fremap[EFX_MAE_FIELD_IP_FIRST_FRAG], + first_frag); + if (rc != 0) + goto fail; + } + } + return 0; fail: @@ -2208,6 +2282,15 @@ static const struct sfc_mae_field_locator flocs_ipv4[] = { RTE_SIZEOF_FIELD(struct rte_flow_item_ipv4, hdr.next_proto_id), offsetof(struct rte_flow_item_ipv4, hdr.next_proto_id), }, + { + /* + * This locator is used only for building supported fields mask. + * The field is handled by sfc_mae_rule_process_pattern_data(). + */ + SFC_MAE_FIELD_HANDLING_DEFERRED, + RTE_SIZEOF_FIELD(struct rte_flow_item_ipv4, hdr.fragment_offset), + offsetof(struct rte_flow_item_ipv4, hdr.fragment_offset), + }, { EFX_MAE_FIELD_IP_TOS, RTE_SIZEOF_FIELD(struct rte_flow_item_ipv4, @@ -2230,14 +2313,30 @@ sfc_mae_rule_parse_item_ipv4(const struct rte_flow_item *item, struct sfc_mae_parse_ctx *ctx_mae = ctx->mae; struct sfc_mae_pattern_data *pdata = &ctx_mae->pattern_data; struct rte_flow_item_ipv4 supp_mask; + struct rte_flow_item item_dup; const uint8_t *spec = NULL; const uint8_t *mask = NULL; + uint8_t *last = NULL; int rc; + item_dup.spec = item->spec; + item_dup.mask = item->mask; + item_dup.last = item->last; + item_dup.type = item->type; + sfc_mae_item_build_supp_mask(flocs_ipv4, RTE_DIM(flocs_ipv4), &supp_mask, sizeof(supp_mask)); - rc = sfc_flow_parse_init(item, + /* We don't support IPv4 fragmentation in the outer frames. */ + if (ctx_mae->match_spec != ctx_mae->match_spec_action) + supp_mask.hdr.fragment_offset = 0; + + if (item != NULL && item->last != NULL) { + last = item->last; + item_dup.last = NULL; + } + + rc = sfc_flow_parse_init(&item_dup, (const void **)&spec, (const void **)&mask, (const void *)&supp_mask, &rte_flow_item_ipv4_mask, @@ -2251,12 +2350,19 @@ sfc_mae_rule_parse_item_ipv4(const struct rte_flow_item *item, if (spec != NULL) { const struct rte_flow_item_ipv4 *item_spec; const struct rte_flow_item_ipv4 *item_mask; + const struct rte_flow_item_ipv4 *item_last; item_spec = (const struct rte_flow_item_ipv4 *)spec; item_mask = (const struct rte_flow_item_ipv4 *)mask; + if (last != NULL) + item_last = (const struct rte_flow_item_ipv4 *)last; pdata->l3_next_proto_value = item_spec->hdr.next_proto_id; pdata->l3_next_proto_mask = item_mask->hdr.next_proto_id; + pdata->l3_frag_ofst_mask = item_mask->hdr.fragment_offset; + pdata->l3_frag_ofst_value = item_spec->hdr.fragment_offset; + if (last != NULL) + pdata->l3_frag_ofst_last = item_last->hdr.fragment_offset; } else { return 0; } @@ -2518,6 +2624,8 @@ static const efx_mae_field_id_t field_ids_no_remap[] = { FIELD_ID_NO_REMAP(TCP_FLAGS_BE), FIELD_ID_NO_REMAP(HAS_OVLAN), FIELD_ID_NO_REMAP(HAS_IVLAN), + FIELD_ID_NO_REMAP(IS_IP_FRAG), + FIELD_ID_NO_REMAP(IP_FIRST_FRAG), #undef FIELD_ID_NO_REMAP }; diff --git a/drivers/net/sfc/sfc_mae.h b/drivers/net/sfc/sfc_mae.h index 80585c0e93..059718e383 100644 --- a/drivers/net/sfc/sfc_mae.h +++ b/drivers/net/sfc/sfc_mae.h @@ -334,6 +334,10 @@ struct sfc_mae_pattern_data { uint8_t l3_next_proto_restriction_value; uint8_t l3_next_proto_restriction_mask; + rte_be16_t l3_frag_ofst_value; + rte_be16_t l3_frag_ofst_mask; + rte_be16_t l3_frag_ofst_last; + /* Projected state of EFX_MAE_FIELD_HAS_OVLAN match bit */ bool has_ovlan_value; bool has_ovlan_mask;