From patchwork Thu Jun 1 19:55:31 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ivan Malov X-Patchwork-Id: 127900 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 ECC4042C07; Thu, 1 Jun 2023 21:58:40 +0200 (CEST) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 7C0A043000; Thu, 1 Jun 2023 21:56:15 +0200 (CEST) Received: from agw.arknetworks.am (agw.arknetworks.am [79.141.165.80]) by mails.dpdk.org (Postfix) with ESMTP id 0CA7C42D7C for ; Thu, 1 Jun 2023 21:55:56 +0200 (CEST) Received: from localhost.localdomain (unknown [78.109.69.146]) (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 919C9E1B5B; Thu, 1 Jun 2023 23:55:55 +0400 (+04) From: Ivan Malov To: dev@dpdk.org Cc: Andrew Rybchenko , Ferruh Yigit , Andy Moreton Subject: [PATCH 27/34] net/sfc: add support for IPv4 NAT offload to MAE backend Date: Thu, 1 Jun 2023 23:55:31 +0400 Message-Id: <20230601195538.8265-28-ivan.malov@arknetworks.am> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20230601195538.8265-1-ivan.malov@arknetworks.am> References: <20230601195538.8265-1-ivan.malov@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 For this offload to work, the innermost pattern items must provide the full set of exact match criteria, which are as follows: EtherType, IP DST, IP SRC, TP protocol ID, TP DST and TP SRC, where the protocol types can be autodetected. The offload requires that the IPv4 and the TP actions be requested simultaneously in the same flow by the caller: SET_IPV4_DST + SET_TP_DST or SET_IPV4_SRC + SET_TP_SRC. The offload operates on the outermost frame, which, if action VXLAN_DECAP was requested, maps to the inner frame of the original packet. The caller is responsible to request this offload only when the target header is an IPv4-based one. Signed-off-by: Ivan Malov Reviewed-by: Andy Moreton --- doc/guides/nics/features/sfc.ini | 4 ++ doc/guides/nics/sfc_efx.rst | 8 ++++ drivers/net/sfc/sfc_mae.c | 77 ++++++++++++++++++++++++++++---- 3 files changed, 81 insertions(+), 8 deletions(-) diff --git a/doc/guides/nics/features/sfc.ini b/doc/guides/nics/features/sfc.ini index f5ac644278..19d4935ce6 100644 --- a/doc/guides/nics/features/sfc.ini +++ b/doc/guides/nics/features/sfc.ini @@ -75,8 +75,12 @@ port_representor = Y represented_port = Y queue = Y rss = Y +set_ipv4_dst = Y +set_ipv4_src = Y set_mac_dst = Y set_mac_src = Y +set_tp_dst = Y +set_tp_src = Y vf = Y vxlan_decap = Y vxlan_encap = Y diff --git a/doc/guides/nics/sfc_efx.rst b/doc/guides/nics/sfc_efx.rst index de0656876b..6e974c3720 100644 --- a/doc/guides/nics/sfc_efx.rst +++ b/doc/guides/nics/sfc_efx.rst @@ -270,10 +270,18 @@ Supported actions (***transfer*** rules): - OF_VLAN_SET_PCP +- SET_IPV4_DST + +- SET_IPV4_SRC + - SET_MAC_DST - SET_MAC_SRC +- SET_TP_DST + +- SET_TP_SRC + - OF_DEC_NW_TTL - DEC_TTL diff --git a/drivers/net/sfc/sfc_mae.c b/drivers/net/sfc/sfc_mae.c index 167426eaf3..c03a43c6dd 100644 --- a/drivers/net/sfc/sfc_mae.c +++ b/drivers/net/sfc/sfc_mae.c @@ -9,6 +9,7 @@ #include +#include #include #include #include @@ -3446,6 +3447,8 @@ sfc_mae_rule_parse_action_set_mac(struct sfc_adapter *sa, enum sfc_mae_actions_bundle_type { SFC_MAE_ACTIONS_BUNDLE_EMPTY = 0, SFC_MAE_ACTIONS_BUNDLE_VLAN_PUSH, + SFC_MAE_ACTIONS_BUNDLE_NAT_DST, + SFC_MAE_ACTIONS_BUNDLE_NAT_SRC, }; struct sfc_mae_actions_bundle { @@ -3466,7 +3469,8 @@ struct sfc_mae_actions_bundle { */ static int sfc_mae_actions_bundle_submit(const struct sfc_mae_actions_bundle *bundle, - efx_mae_actions_t *spec) + struct sfc_flow_spec_mae *flow_spec, + bool ct, efx_mae_actions_t *spec) { int rc = 0; @@ -3477,6 +3481,16 @@ sfc_mae_actions_bundle_submit(const struct sfc_mae_actions_bundle *bundle, rc = efx_mae_action_set_populate_vlan_push( spec, bundle->vlan_push_tpid, bundle->vlan_push_tci); break; + case SFC_MAE_ACTIONS_BUNDLE_NAT_DST: + flow_spec->ct_resp.nat.dir_is_dst = true; + /* FALLTHROUGH */ + case SFC_MAE_ACTIONS_BUNDLE_NAT_SRC: + if (ct && flow_spec->ct_resp.nat.ip_le != 0 && + flow_spec->ct_resp.nat.port_le != 0) + rc = efx_mae_action_set_populate_nat(spec); + else + rc = EINVAL; + break; default: SFC_ASSERT(B_FALSE); break; @@ -3493,7 +3507,8 @@ sfc_mae_actions_bundle_submit(const struct sfc_mae_actions_bundle *bundle, static int sfc_mae_actions_bundle_sync(const struct rte_flow_action *action, struct sfc_mae_actions_bundle *bundle, - efx_mae_actions_t *spec, + struct sfc_flow_spec_mae *flow_spec, + efx_mae_actions_t *spec, bool ct, struct rte_flow_error *error) { enum sfc_mae_actions_bundle_type bundle_type_new; @@ -3505,6 +3520,14 @@ sfc_mae_actions_bundle_sync(const struct rte_flow_action *action, case RTE_FLOW_ACTION_TYPE_OF_SET_VLAN_PCP: bundle_type_new = SFC_MAE_ACTIONS_BUNDLE_VLAN_PUSH; break; + case RTE_FLOW_ACTION_TYPE_SET_IPV4_DST: + case RTE_FLOW_ACTION_TYPE_SET_TP_DST: + bundle_type_new = SFC_MAE_ACTIONS_BUNDLE_NAT_DST; + break; + case RTE_FLOW_ACTION_TYPE_SET_IPV4_SRC: + case RTE_FLOW_ACTION_TYPE_SET_TP_SRC: + bundle_type_new = SFC_MAE_ACTIONS_BUNDLE_NAT_SRC; + break; default: /* * Self-sufficient actions, including END, are handled in this @@ -3517,7 +3540,7 @@ sfc_mae_actions_bundle_sync(const struct rte_flow_action *action, if (bundle_type_new != bundle->type || (bundle->actions_mask & (1ULL << action->type)) != 0) { - rc = sfc_mae_actions_bundle_submit(bundle, spec); + rc = sfc_mae_actions_bundle_submit(bundle, flow_spec, ct, spec); if (rc != 0) goto fail_submit; @@ -3534,6 +3557,20 @@ sfc_mae_actions_bundle_sync(const struct rte_flow_action *action, "Failed to request the (group of) action(s)"); } +static void +sfc_mae_rule_parse_action_nat_addr(const struct rte_flow_action_set_ipv4 *conf, + uint32_t *nat_addr_le) +{ + *nat_addr_le = rte_bswap32(conf->ipv4_addr); +} + +static void +sfc_mae_rule_parse_action_nat_port(const struct rte_flow_action_set_tp *conf, + uint16_t *nat_port_le) +{ + *nat_port_le = rte_bswap16(conf->port); +} + static void sfc_mae_rule_parse_action_of_push_vlan( const struct rte_flow_action_of_push_vlan *conf, @@ -4058,6 +4095,10 @@ static const char * const action_names[] = { [RTE_FLOW_ACTION_TYPE_SET_MAC_SRC] = "SET_MAC_SRC", [RTE_FLOW_ACTION_TYPE_OF_DEC_NW_TTL] = "OF_DEC_NW_TTL", [RTE_FLOW_ACTION_TYPE_DEC_TTL] = "DEC_TTL", + [RTE_FLOW_ACTION_TYPE_SET_IPV4_DST] = "SET_IPV4_DST", + [RTE_FLOW_ACTION_TYPE_SET_IPV4_SRC] = "SET_IPV4_SRC", + [RTE_FLOW_ACTION_TYPE_SET_TP_DST] = "SET_TP_DST", + [RTE_FLOW_ACTION_TYPE_SET_TP_SRC] = "SET_TP_SRC", [RTE_FLOW_ACTION_TYPE_OF_PUSH_VLAN] = "OF_PUSH_VLAN", [RTE_FLOW_ACTION_TYPE_OF_SET_VLAN_VID] = "OF_SET_VLAN_VID", [RTE_FLOW_ACTION_TYPE_OF_SET_VLAN_PCP] = "OF_SET_VLAN_PCP", @@ -4077,12 +4118,12 @@ static const char * const action_names[] = { static int sfc_mae_rule_parse_action(struct sfc_adapter *sa, const struct rte_flow_action *action, - const struct rte_flow *flow, + struct rte_flow *flow, struct sfc_mae_actions_bundle *bundle, struct sfc_mae_aset_ctx *ctx, struct rte_flow_error *error) { - const struct sfc_flow_spec_mae *spec_mae = &flow->spec.mae; + struct sfc_flow_spec_mae *spec_mae = &flow->spec.mae; const struct sfc_mae_outer_rule *outer_rule = spec_mae->outer_rule; const uint64_t rx_metadata = sa->negotiated_rx_metadata; efx_mae_actions_t *spec = ctx->spec; @@ -4129,6 +4170,24 @@ sfc_mae_rule_parse_action(struct sfc_adapter *sa, bundle->actions_mask); rc = efx_mae_action_set_populate_decr_ip_ttl(spec); break; + case RTE_FLOW_ACTION_TYPE_SET_IPV4_DST: + case RTE_FLOW_ACTION_TYPE_SET_IPV4_SRC: + SFC_BUILD_SET_OVERFLOW(RTE_FLOW_ACTION_TYPE_SET_IPV4_DST, + bundle->actions_mask); + SFC_BUILD_SET_OVERFLOW(RTE_FLOW_ACTION_TYPE_SET_IPV4_SRC, + bundle->actions_mask); + sfc_mae_rule_parse_action_nat_addr(action->conf, + &spec_mae->ct_resp.nat.ip_le); + break; + case RTE_FLOW_ACTION_TYPE_SET_TP_DST: + case RTE_FLOW_ACTION_TYPE_SET_TP_SRC: + SFC_BUILD_SET_OVERFLOW(RTE_FLOW_ACTION_TYPE_SET_TP_DST, + bundle->actions_mask); + SFC_BUILD_SET_OVERFLOW(RTE_FLOW_ACTION_TYPE_SET_TP_SRC, + bundle->actions_mask); + sfc_mae_rule_parse_action_nat_port(action->conf, + &spec_mae->ct_resp.nat.port_le); + break; case RTE_FLOW_ACTION_TYPE_OF_PUSH_VLAN: SFC_BUILD_SET_OVERFLOW(RTE_FLOW_ACTION_TYPE_OF_PUSH_VLAN, bundle->actions_mask); @@ -4287,6 +4346,7 @@ sfc_mae_rule_parse_actions(struct sfc_adapter *sa, { struct sfc_flow_spec_mae *spec_mae = &flow->spec.mae; struct sfc_mae_actions_bundle bundle = {0}; + bool ct = (action_rule_ctx->ct_mark != 0); const struct rte_flow_action *action; struct sfc_mae_aset_ctx ctx = {0}; struct sfc_mae *mae = &sa->mae; @@ -4337,8 +4397,8 @@ sfc_mae_rule_parse_actions(struct sfc_adapter *sa, for (action = actions; action->type != RTE_FLOW_ACTION_TYPE_END; ++action) { - rc = sfc_mae_actions_bundle_sync(action, &bundle, - ctx.spec, error); + rc = sfc_mae_actions_bundle_sync(action, &bundle, spec_mae, + ctx.spec, ct, error); if (rc != 0) goto fail_rule_parse_action; @@ -4348,7 +4408,8 @@ sfc_mae_rule_parse_actions(struct sfc_adapter *sa, goto fail_rule_parse_action; } - rc = sfc_mae_actions_bundle_sync(action, &bundle, ctx.spec, error); + rc = sfc_mae_actions_bundle_sync(action, &bundle, spec_mae, + ctx.spec, ct, error); if (rc != 0) goto fail_rule_parse_action;