DPDK patches and discussions
 help / color / mirror / Atom feed
* [PATCH 0/4] net/sfc: support MAC address edits in transfer flows
@ 2021-11-17 11:44 Ivan Malov
  2021-11-17 11:44 ` [PATCH 1/4] net/sfc: refine the order of checks on MAE action set attach Ivan Malov
                   ` (4 more replies)
  0 siblings, 5 replies; 6+ messages in thread
From: Ivan Malov @ 2021-11-17 11:44 UTC (permalink / raw)
  To: dev

Ivan Malov (4):
  net/sfc: refine the order of checks on MAE action set attach
  net/sfc: organise MAE flow action parsing function arguments
  common/sfc_efx/base: support MAC address edit actions in MAE
  net/sfc: support MAC address edits in transfer flows

 doc/guides/nics/features/sfc.ini       |   2 +
 doc/guides/nics/sfc_efx.rst            |   4 +
 drivers/common/sfc_efx/base/efx.h      |  60 ++++
 drivers/common/sfc_efx/base/efx_impl.h |   4 +
 drivers/common/sfc_efx/base/efx_mae.c  | 303 ++++++++++++++++++-
 drivers/common/sfc_efx/version.map     |   6 +
 drivers/net/sfc/sfc_mae.c              | 403 +++++++++++++++++++++----
 drivers/net/sfc/sfc_mae.h              |  15 +
 8 files changed, 730 insertions(+), 67 deletions(-)

-- 
2.30.2


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH 1/4] net/sfc: refine the order of checks on MAE action set attach
  2021-11-17 11:44 [PATCH 0/4] net/sfc: support MAC address edits in transfer flows Ivan Malov
@ 2021-11-17 11:44 ` Ivan Malov
  2021-11-17 11:44 ` [PATCH 2/4] net/sfc: organise MAE flow action parsing function arguments Ivan Malov
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Ivan Malov @ 2021-11-17 11:44 UTC (permalink / raw)
  To: dev; +Cc: Andrew Rybchenko, Andy Moreton

The number of counters being non-zero can be detected before
the action set registry traversal, so move the check outside.

Signed-off-by: Ivan Malov <ivan.malov@oktetlabs.ru>
Reviewed-by: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>
Reviewed-by: Andy Moreton <amoreton@xilinx.com>
---
 drivers/net/sfc/sfc_mae.c | 12 +++++++-----
 1 file changed, 7 insertions(+), 5 deletions(-)

diff --git a/drivers/net/sfc/sfc_mae.c b/drivers/net/sfc/sfc_mae.c
index 08e28b13c9..73bedf5088 100644
--- a/drivers/net/sfc/sfc_mae.c
+++ b/drivers/net/sfc/sfc_mae.c
@@ -763,13 +763,15 @@ sfc_mae_action_set_attach(struct sfc_adapter *sa,
 
 	SFC_ASSERT(sfc_adapter_is_locked(sa));
 
+	/*
+	 * Shared counters are not supported, hence, action
+	 * sets with counters are not attachable.
+	 */
+	if (n_count != 0)
+		return NULL;
+
 	TAILQ_FOREACH(action_set, &mae->action_sets, entries) {
-		/*
-		 * Shared counters are not supported, hence action sets with
-		 * COUNT are not attachable.
-		 */
 		if (action_set->encap_header == encap_header &&
-		    n_count == 0 &&
 		    efx_mae_action_set_specs_equal(action_set->spec, spec)) {
 			sfc_dbg(sa, "attaching to action_set=%p", action_set);
 			++(action_set->refcnt);
-- 
2.30.2


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH 2/4] net/sfc: organise MAE flow action parsing function arguments
  2021-11-17 11:44 [PATCH 0/4] net/sfc: support MAC address edits in transfer flows Ivan Malov
  2021-11-17 11:44 ` [PATCH 1/4] net/sfc: refine the order of checks on MAE action set attach Ivan Malov
@ 2021-11-17 11:44 ` Ivan Malov
  2021-11-17 11:44 ` [PATCH 3/4] common/sfc_efx/base: support MAC address edit actions in MAE Ivan Malov
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Ivan Malov @ 2021-11-17 11:44 UTC (permalink / raw)
  To: dev; +Cc: Andrew Rybchenko, Andy Moreton

Add a context structure to simplify handling of action sets.

Signed-off-by: Ivan Malov <ivan.malov@oktetlabs.ru>
Reviewed-by: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>
Reviewed-by: Andy Moreton <amoreton@xilinx.com>
---
 drivers/net/sfc/sfc_mae.c | 103 +++++++++++++++++++-------------------
 1 file changed, 52 insertions(+), 51 deletions(-)

diff --git a/drivers/net/sfc/sfc_mae.c b/drivers/net/sfc/sfc_mae.c
index 73bedf5088..b7a148afae 100644
--- a/drivers/net/sfc/sfc_mae.c
+++ b/drivers/net/sfc/sfc_mae.c
@@ -752,11 +752,18 @@ sfc_mae_counters_disable(struct sfc_adapter *sa,
 	return sfc_mae_counter_disable(sa, &counters[0]);
 }
 
+struct sfc_mae_aset_ctx {
+	uint64_t			*ft_group_hit_counter;
+	struct sfc_mae_encap_header	*encap_header;
+	struct sfc_flow_tunnel		*counter_ft;
+	unsigned int			n_counters;
+
+	efx_mae_actions_t		*spec;
+};
+
 static struct sfc_mae_action_set *
 sfc_mae_action_set_attach(struct sfc_adapter *sa,
-			  const struct sfc_mae_encap_header *encap_header,
-			  unsigned int n_count,
-			  const efx_mae_actions_t *spec)
+			  const struct sfc_mae_aset_ctx *ctx)
 {
 	struct sfc_mae_action_set *action_set;
 	struct sfc_mae *mae = &sa->mae;
@@ -767,12 +774,13 @@ sfc_mae_action_set_attach(struct sfc_adapter *sa,
 	 * Shared counters are not supported, hence, action
 	 * sets with counters are not attachable.
 	 */
-	if (n_count != 0)
+	if (ctx->n_counters != 0)
 		return NULL;
 
 	TAILQ_FOREACH(action_set, &mae->action_sets, entries) {
-		if (action_set->encap_header == encap_header &&
-		    efx_mae_action_set_specs_equal(action_set->spec, spec)) {
+		if (action_set->encap_header == ctx->encap_header &&
+		    efx_mae_action_set_specs_equal(action_set->spec,
+						   ctx->spec)) {
 			sfc_dbg(sa, "attaching to action_set=%p", action_set);
 			++(action_set->refcnt);
 			return action_set;
@@ -785,11 +793,7 @@ sfc_mae_action_set_attach(struct sfc_adapter *sa,
 static int
 sfc_mae_action_set_add(struct sfc_adapter *sa,
 		       const struct rte_flow_action actions[],
-		       efx_mae_actions_t *spec,
-		       struct sfc_mae_encap_header *encap_header,
-		       uint64_t *ft_group_hit_counter,
-		       struct sfc_flow_tunnel *ft,
-		       unsigned int n_counters,
+		       const struct sfc_mae_aset_ctx *ctx,
 		       struct sfc_mae_action_set **action_setp)
 {
 	struct sfc_mae_action_set *action_set;
@@ -804,30 +808,30 @@ sfc_mae_action_set_add(struct sfc_adapter *sa,
 		return ENOMEM;
 	}
 
-	if (n_counters > 0) {
+	if (ctx->n_counters > 0) {
 		const struct rte_flow_action *action;
 
 		action_set->counters = rte_malloc("sfc_mae_counter_ids",
-			sizeof(action_set->counters[0]) * n_counters, 0);
+			sizeof(action_set->counters[0]) * ctx->n_counters, 0);
 		if (action_set->counters == NULL) {
 			rte_free(action_set);
 			sfc_err(sa, "failed to alloc counters");
 			return ENOMEM;
 		}
 
-		for (i = 0; i < n_counters; ++i) {
+		for (i = 0; i < ctx->n_counters; ++i) {
 			action_set->counters[i].rte_id_valid = B_FALSE;
 			action_set->counters[i].mae_id.id =
 				EFX_MAE_RSRC_ID_INVALID;
 
 			action_set->counters[i].ft_group_hit_counter =
-				ft_group_hit_counter;
-			action_set->counters[i].ft = ft;
+				ctx->ft_group_hit_counter;
+			action_set->counters[i].ft = ctx->counter_ft;
 		}
 
 		for (action = actions, i = 0;
-		     action->type != RTE_FLOW_ACTION_TYPE_END && i < n_counters;
-		     ++action) {
+		     action->type != RTE_FLOW_ACTION_TYPE_END &&
+		     i < ctx->n_counters; ++action) {
 			const struct rte_flow_action_count *conf;
 
 			if (action->type != RTE_FLOW_ACTION_TYPE_COUNT)
@@ -839,12 +843,12 @@ sfc_mae_action_set_add(struct sfc_adapter *sa,
 			action_set->counters[i].rte_id = conf->id;
 			i++;
 		}
-		action_set->n_counters = n_counters;
+		action_set->n_counters = ctx->n_counters;
 	}
 
 	action_set->refcnt = 1;
-	action_set->spec = spec;
-	action_set->encap_header = encap_header;
+	action_set->spec = ctx->spec;
+	action_set->encap_header = ctx->encap_header;
 
 	action_set->fw_rsrc.aset_id.id = EFX_MAE_RSRC_ID_INVALID;
 
@@ -3752,14 +3756,10 @@ sfc_mae_rule_parse_actions(struct sfc_adapter *sa,
 			   struct sfc_flow_spec_mae *spec_mae,
 			   struct rte_flow_error *error)
 {
-	struct sfc_mae_encap_header *encap_header = NULL;
 	struct sfc_mae_actions_bundle bundle = {0};
-	struct sfc_flow_tunnel *counter_ft = NULL;
-	uint64_t *ft_group_hit_counter = NULL;
 	const struct rte_flow_action *action;
+	struct sfc_mae_aset_ctx ctx = {0};
 	struct sfc_mae *mae = &sa->mae;
-	unsigned int n_count = 0;
-	efx_mae_actions_t *spec;
 	int rc;
 
 	rte_errno = 0;
@@ -3770,34 +3770,35 @@ sfc_mae_rule_parse_actions(struct sfc_adapter *sa,
 				"NULL actions");
 	}
 
-	rc = efx_mae_action_set_spec_init(sa->nic, &spec);
+	rc = efx_mae_action_set_spec_init(sa->nic, &ctx.spec);
 	if (rc != 0)
 		goto fail_action_set_spec_init;
 
 	for (action = actions;
 	     action->type != RTE_FLOW_ACTION_TYPE_END; ++action) {
 		if (action->type == RTE_FLOW_ACTION_TYPE_COUNT)
-			++n_count;
+			++(ctx.n_counters);
 	}
 
 	if (spec_mae->ft_rule_type == SFC_FT_RULE_GROUP) {
 		/* JUMP rules don't decapsulate packets. GROUP rules do. */
-		rc = efx_mae_action_set_populate_decap(spec);
+		rc = efx_mae_action_set_populate_decap(ctx.spec);
 		if (rc != 0)
 			goto fail_enforce_ft_decap;
 
-		if (n_count == 0 && sfc_mae_counter_stream_enabled(sa)) {
+		if (ctx.n_counters == 0 &&
+		    sfc_mae_counter_stream_enabled(sa)) {
 			/*
 			 * The user opted not to use action COUNT in this rule,
 			 * but the counter should be enabled implicitly because
 			 * packets hitting this rule contribute to the tunnel's
 			 * total number of hits. See sfc_mae_counter_get().
 			 */
-			rc = efx_mae_action_set_populate_count(spec);
+			rc = efx_mae_action_set_populate_count(ctx.spec);
 			if (rc != 0)
 				goto fail_enforce_ft_count;
 
-			n_count = 1;
+			ctx.n_counters = 1;
 		}
 	}
 
@@ -3806,27 +3807,30 @@ 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, spec, error);
+		rc = sfc_mae_actions_bundle_sync(action, &bundle,
+						 ctx.spec, error);
 		if (rc != 0)
 			goto fail_rule_parse_action;
 
 		rc = sfc_mae_rule_parse_action(sa, action, spec_mae,
-					       &bundle, spec, error);
+					       &bundle, ctx.spec, error);
 		if (rc != 0)
 			goto fail_rule_parse_action;
 	}
 
-	rc = sfc_mae_actions_bundle_sync(action, &bundle, spec, error);
+	rc = sfc_mae_actions_bundle_sync(action, &bundle, ctx.spec, error);
 	if (rc != 0)
 		goto fail_rule_parse_action;
 
-	rc = sfc_mae_process_encap_header(sa, &mae->bounce_eh, &encap_header);
+	rc = sfc_mae_process_encap_header(sa, &mae->bounce_eh,
+					  &ctx.encap_header);
 	if (rc != 0)
 		goto fail_process_encap_header;
 
-	if (n_count > 1) {
+	if (ctx.n_counters > 1) {
 		rc = ENOTSUP;
-		sfc_err(sa, "too many count actions requested: %u", n_count);
+		sfc_err(sa, "too many count actions requested: %u",
+			ctx.n_counters);
 		goto fail_nb_count;
 	}
 
@@ -3835,11 +3839,11 @@ sfc_mae_rule_parse_actions(struct sfc_adapter *sa,
 		break;
 	case SFC_FT_RULE_JUMP:
 		/* Workaround. See sfc_flow_parse_rte_to_mae() */
-		rc = sfc_mae_rule_parse_action_pf_vf(sa, NULL, spec);
+		rc = sfc_mae_rule_parse_action_pf_vf(sa, NULL, ctx.spec);
 		if (rc != 0)
 			goto fail_workaround_jump_delivery;
 
-		counter_ft = spec_mae->ft;
+		ctx.counter_ft = spec_mae->ft;
 		break;
 	case SFC_FT_RULE_GROUP:
 		/*
@@ -3848,25 +3852,22 @@ sfc_mae_rule_parse_actions(struct sfc_adapter *sa,
 		 * packets. The user may have provided their own action
 		 * MARK above, so don't check the return value here.
 		 */
-		(void)efx_mae_action_set_populate_mark(spec, 0);
+		(void)efx_mae_action_set_populate_mark(ctx.spec, 0);
 
-		ft_group_hit_counter = &spec_mae->ft->group_hit_counter;
+		ctx.ft_group_hit_counter = &spec_mae->ft->group_hit_counter;
 		break;
 	default:
 		SFC_ASSERT(B_FALSE);
 	}
 
-	spec_mae->action_set = sfc_mae_action_set_attach(sa, encap_header,
-							 n_count, spec);
+	spec_mae->action_set = sfc_mae_action_set_attach(sa, &ctx);
 	if (spec_mae->action_set != NULL) {
-		sfc_mae_encap_header_del(sa, encap_header);
-		efx_mae_action_set_spec_fini(sa->nic, spec);
+		sfc_mae_encap_header_del(sa, ctx.encap_header);
+		efx_mae_action_set_spec_fini(sa->nic, ctx.spec);
 		return 0;
 	}
 
-	rc = sfc_mae_action_set_add(sa, actions, spec, encap_header,
-				    ft_group_hit_counter, counter_ft, n_count,
-				    &spec_mae->action_set);
+	rc = sfc_mae_action_set_add(sa, actions, &ctx, &spec_mae->action_set);
 	if (rc != 0)
 		goto fail_action_set_add;
 
@@ -3875,11 +3876,11 @@ sfc_mae_rule_parse_actions(struct sfc_adapter *sa,
 fail_action_set_add:
 fail_workaround_jump_delivery:
 fail_nb_count:
-	sfc_mae_encap_header_del(sa, encap_header);
+	sfc_mae_encap_header_del(sa, ctx.encap_header);
 
 fail_process_encap_header:
 fail_rule_parse_action:
-	efx_mae_action_set_spec_fini(sa->nic, spec);
+	efx_mae_action_set_spec_fini(sa->nic, ctx.spec);
 
 fail_enforce_ft_count:
 fail_enforce_ft_decap:
-- 
2.30.2


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH 3/4] common/sfc_efx/base: support MAC address edit actions in MAE
  2021-11-17 11:44 [PATCH 0/4] net/sfc: support MAC address edits in transfer flows Ivan Malov
  2021-11-17 11:44 ` [PATCH 1/4] net/sfc: refine the order of checks on MAE action set attach Ivan Malov
  2021-11-17 11:44 ` [PATCH 2/4] net/sfc: organise MAE flow action parsing function arguments Ivan Malov
@ 2021-11-17 11:44 ` Ivan Malov
  2021-11-17 11:44 ` [PATCH 4/4] net/sfc: support MAC address edits in transfer flows Ivan Malov
  2021-11-17 13:17 ` [PATCH 0/4] " Ferruh Yigit
  4 siblings, 0 replies; 6+ messages in thread
From: Ivan Malov @ 2021-11-17 11:44 UTC (permalink / raw)
  To: dev; +Cc: Andrew Rybchenko, Andy Moreton, Ray Kinsella

In a tunnel packet, these actions affect the inner header if
action DECAP is set; otherwise, they affect the outer header.

Adding these actions is done in two steps: add the action to
the action mask and indicate the MAC address entry ID to use.
This allows the user to check the order of actions first and
allocate resources when time comes to enable the action rule.

Signed-off-by: Ivan Malov <ivan.malov@oktetlabs.ru>
Reviewed-by: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>
Reviewed-by: Andy Moreton <amoreton@xilinx.com>
---
 drivers/common/sfc_efx/base/efx.h      |  60 +++++
 drivers/common/sfc_efx/base/efx_impl.h |   4 +
 drivers/common/sfc_efx/base/efx_mae.c  | 303 ++++++++++++++++++++++++-
 drivers/common/sfc_efx/version.map     |   6 +
 4 files changed, 363 insertions(+), 10 deletions(-)

diff --git a/drivers/common/sfc_efx/base/efx.h b/drivers/common/sfc_efx/base/efx.h
index f08a004536..62eead638a 100644
--- a/drivers/common/sfc_efx/base/efx.h
+++ b/drivers/common/sfc_efx/base/efx.h
@@ -4437,6 +4437,34 @@ extern	__checkReturn			efx_rc_t
 efx_mae_action_set_populate_vlan_pop(
 	__in				efx_mae_actions_t *spec);
 
+/*
+ * This always amends the outermost header. This way, for a tunnel
+ * packet, if action DECAP is not requested, this will affect the
+ * outer header; otherwise, the inner header will be updated.
+ *
+ * Use efx_mae_action_set_fill_in_dst_mac_id() to set ID of
+ * the allocated MAC address entry in the specification
+ * prior to action set allocation.
+ */
+LIBEFX_API
+extern	__checkReturn			efx_rc_t
+efx_mae_action_set_populate_set_dst_mac(
+	__in				efx_mae_actions_t *spec);
+
+/*
+ * This always amends the outermost header. This way, for a tunnel
+ * packet, if action DECAP is not requested, this will affect the
+ * outer header; otherwise, the inner header will be updated.
+ *
+ * Use efx_mae_action_set_fill_in_src_mac_id() to set ID of
+ * the allocated MAC address entry in the specification
+ * prior to action set allocation.
+ */
+LIBEFX_API
+extern	__checkReturn			efx_rc_t
+efx_mae_action_set_populate_set_src_mac(
+	__in				efx_mae_actions_t *spec);
+
 /*
  * This always amends the outermost header. This way, for a tunnel
  * packet, if action DECAP is not requested, this will affect the
@@ -4570,6 +4598,38 @@ efx_mae_match_spec_outer_rule_id_set(
 	__in				efx_mae_match_spec_t *spec,
 	__in				const efx_mae_rule_id_t *or_idp);
 
+/* MAC address entry ID */
+typedef struct efx_mae_mac_id_s {
+	uint32_t id;
+} efx_mae_mac_id_t;
+
+LIBEFX_API
+extern	__checkReturn	efx_rc_t
+efx_mae_mac_addr_alloc(
+	__in		efx_nic_t *enp,
+	__in		uint8_t addr_bytes[EFX_MAC_ADDR_LEN],
+	__out		efx_mae_mac_id_t *mac_idp);
+
+LIBEFX_API
+extern	__checkReturn	efx_rc_t
+efx_mae_mac_addr_free(
+	__in		efx_nic_t *enp,
+	__in		const efx_mae_mac_id_t *mac_idp);
+
+/* See description before efx_mae_action_set_populate_set_dst_mac(). */
+LIBEFX_API
+extern	__checkReturn			efx_rc_t
+efx_mae_action_set_fill_in_dst_mac_id(
+	__in				efx_mae_actions_t *spec,
+	__in				const efx_mae_mac_id_t *mac_idp);
+
+/* See description before efx_mae_action_set_populate_set_src_mac(). */
+LIBEFX_API
+extern	__checkReturn			efx_rc_t
+efx_mae_action_set_fill_in_src_mac_id(
+	__in				efx_mae_actions_t *spec,
+	__in				const efx_mae_mac_id_t *mac_idp);
+
 /* Encap. header ID */
 typedef struct efx_mae_eh_id_s {
 	uint32_t id;
diff --git a/drivers/common/sfc_efx/base/efx_impl.h b/drivers/common/sfc_efx/base/efx_impl.h
index eda41b4be0..d181040186 100644
--- a/drivers/common/sfc_efx/base/efx_impl.h
+++ b/drivers/common/sfc_efx/base/efx_impl.h
@@ -1740,6 +1740,8 @@ typedef enum efx_mae_action_e {
 	/* These actions are strictly ordered. */
 	EFX_MAE_ACTION_DECAP,
 	EFX_MAE_ACTION_VLAN_POP,
+	EFX_MAE_ACTION_SET_DST_MAC,
+	EFX_MAE_ACTION_SET_SRC_MAC,
 	EFX_MAE_ACTION_DECR_IP_TTL,
 	EFX_MAE_ACTION_VLAN_PUSH,
 	EFX_MAE_ACTION_COUNT,
@@ -1772,6 +1774,8 @@ typedef struct efx_mae_action_vlan_push_s {
 } efx_mae_action_vlan_push_t;
 
 typedef struct efx_mae_actions_rsrc_s {
+	efx_mae_mac_id_t		emar_dst_mac_id;
+	efx_mae_mac_id_t		emar_src_mac_id;
 	efx_mae_eh_id_t			emar_eh_id;
 	efx_counter_t			emar_counter_id;
 } efx_mae_actions_rsrc_t;
diff --git a/drivers/common/sfc_efx/base/efx_mae.c b/drivers/common/sfc_efx/base/efx_mae.c
index 756c35788e..7b24e3fee4 100644
--- a/drivers/common/sfc_efx/base/efx_mae.c
+++ b/drivers/common/sfc_efx/base/efx_mae.c
@@ -1386,6 +1386,8 @@ efx_mae_action_set_spec_init(
 		goto fail1;
 	}
 
+	spec->ema_rsrc.emar_dst_mac_id.id = EFX_MAE_RSRC_ID_INVALID;
+	spec->ema_rsrc.emar_src_mac_id.id = EFX_MAE_RSRC_ID_INVALID;
 	spec->ema_rsrc.emar_eh_id.id = EFX_MAE_RSRC_ID_INVALID;
 	spec->ema_rsrc.emar_counter_id.id = EFX_MAE_RSRC_ID_INVALID;
 
@@ -1633,6 +1635,12 @@ static const efx_mae_action_desc_t efx_mae_actions[EFX_MAE_NACTIONS] = {
 	[EFX_MAE_ACTION_VLAN_POP] = {
 		.emad_add = efx_mae_action_set_add_vlan_pop
 	},
+	[EFX_MAE_ACTION_SET_DST_MAC] = {
+		.emad_add = efx_mae_action_set_no_op
+	},
+	[EFX_MAE_ACTION_SET_SRC_MAC] = {
+		.emad_add = efx_mae_action_set_no_op
+	},
 	[EFX_MAE_ACTION_DECR_IP_TTL] = {
 		.emad_add = efx_mae_action_set_no_op
 	},
@@ -1659,6 +1667,8 @@ static const efx_mae_action_desc_t efx_mae_actions[EFX_MAE_NACTIONS] = {
 static const uint32_t efx_mae_action_ordered_map =
 	(1U << EFX_MAE_ACTION_DECAP) |
 	(1U << EFX_MAE_ACTION_VLAN_POP) |
+	(1U << EFX_MAE_ACTION_SET_DST_MAC) |
+	(1U << EFX_MAE_ACTION_SET_SRC_MAC) |
 	(1U << EFX_MAE_ACTION_DECR_IP_TTL) |
 	(1U << EFX_MAE_ACTION_VLAN_PUSH) |
 	/*
@@ -1778,6 +1788,44 @@ efx_mae_action_set_populate_vlan_pop(
 	    EFX_MAE_ACTION_VLAN_POP, 0, NULL));
 }
 
+	__checkReturn			efx_rc_t
+efx_mae_action_set_populate_set_dst_mac(
+	__in				efx_mae_actions_t *spec)
+{
+	efx_rc_t rc;
+
+	if (spec->ema_v2_is_supported == B_FALSE) {
+		rc = ENOTSUP;
+		goto fail1;
+	}
+
+	return (efx_mae_action_set_spec_populate(spec,
+	    EFX_MAE_ACTION_SET_DST_MAC, 0, NULL));
+
+fail1:
+	EFSYS_PROBE1(fail1, efx_rc_t, rc);
+	return (rc);
+}
+
+	__checkReturn			efx_rc_t
+efx_mae_action_set_populate_set_src_mac(
+	__in				efx_mae_actions_t *spec)
+{
+	efx_rc_t rc;
+
+	if (spec->ema_v2_is_supported == B_FALSE) {
+		rc = ENOTSUP;
+		goto fail1;
+	}
+
+	return (efx_mae_action_set_spec_populate(spec,
+	    EFX_MAE_ACTION_SET_SRC_MAC, 0, NULL));
+
+fail1:
+	EFSYS_PROBE1(fail1, efx_rc_t, rc);
+	return (rc);
+}
+
 	__checkReturn			efx_rc_t
 efx_mae_action_set_populate_decr_ip_ttl(
 	__in				efx_mae_actions_t *spec)
@@ -2317,6 +2365,224 @@ efx_mae_match_spec_outer_rule_id_set(
 
 	return (0);
 
+fail3:
+	EFSYS_PROBE(fail3);
+fail2:
+	EFSYS_PROBE(fail2);
+fail1:
+	EFSYS_PROBE1(fail1, efx_rc_t, rc);
+	return (rc);
+}
+
+	 __checkReturn	efx_rc_t
+efx_mae_mac_addr_alloc(
+	__in		efx_nic_t *enp,
+	__in		uint8_t addr_bytes[EFX_MAC_ADDR_LEN],
+	__out		efx_mae_mac_id_t *mac_idp)
+{
+	const efx_nic_cfg_t *encp = efx_nic_cfg_get(enp);
+	efx_mcdi_req_t req;
+	EFX_MCDI_DECLARE_BUF(payload,
+	    MC_CMD_MAE_MAC_ADDR_ALLOC_IN_LEN,
+	    MC_CMD_MAE_MAC_ADDR_ALLOC_OUT_LEN);
+	efx_mae_mac_id_t mac_id;
+	efx_rc_t rc;
+
+	EFX_STATIC_ASSERT(sizeof (mac_idp->id) ==
+	    MC_CMD_MAE_MAC_ADDR_ALLOC_OUT_MAC_ID_LEN);
+
+	EFX_STATIC_ASSERT(EFX_MAE_RSRC_ID_INVALID ==
+	    MC_CMD_MAE_MAC_ADDR_ALLOC_OUT_MAC_ID_NULL);
+
+	if (encp->enc_mae_supported == B_FALSE) {
+		rc = ENOTSUP;
+		goto fail1;
+	}
+
+	if (encp->enc_mae_aset_v2_supported == B_FALSE) {
+		rc = ENOTSUP;
+		goto fail2;
+	}
+
+	req.emr_cmd = MC_CMD_MAE_MAC_ADDR_ALLOC;
+	req.emr_in_buf = payload;
+	req.emr_in_length = MC_CMD_MAE_MAC_ADDR_ALLOC_IN_LEN;
+	req.emr_out_buf = payload;
+	req.emr_out_length = MC_CMD_MAE_MAC_ADDR_ALLOC_OUT_LEN;
+
+	memcpy(payload + MC_CMD_MAE_MAC_ADDR_ALLOC_IN_MAC_ADDR_OFST,
+	    addr_bytes, EFX_MAC_ADDR_LEN);
+
+	efx_mcdi_execute(enp, &req);
+
+	if (req.emr_rc != 0) {
+		rc = req.emr_rc;
+		goto fail3;
+	}
+
+	if (req.emr_out_length_used < MC_CMD_MAE_MAC_ADDR_ALLOC_OUT_LEN) {
+		rc = EMSGSIZE;
+		goto fail4;
+	}
+
+	mac_id.id = MCDI_OUT_DWORD(req, MAE_MAC_ADDR_ALLOC_OUT_MAC_ID);
+	if (mac_id.id == EFX_MAE_RSRC_ID_INVALID) {
+		rc = ENOENT;
+		goto fail5;
+	}
+
+	mac_idp->id = mac_id.id;
+
+	return (0);
+
+fail5:
+	EFSYS_PROBE(fail5);
+fail4:
+	EFSYS_PROBE(fail4);
+fail3:
+	EFSYS_PROBE(fail3);
+fail2:
+	EFSYS_PROBE(fail2);
+fail1:
+	EFSYS_PROBE1(fail1, efx_rc_t, rc);
+	return (rc);
+}
+
+	__checkReturn	efx_rc_t
+efx_mae_mac_addr_free(
+	__in		efx_nic_t *enp,
+	__in		const efx_mae_mac_id_t *mac_idp)
+{
+	const efx_nic_cfg_t *encp = efx_nic_cfg_get(enp);
+	efx_mcdi_req_t req;
+	EFX_MCDI_DECLARE_BUF(payload,
+	    MC_CMD_MAE_MAC_ADDR_FREE_IN_LEN(1),
+	    MC_CMD_MAE_MAC_ADDR_FREE_OUT_LEN(1));
+	efx_rc_t rc;
+
+	if (encp->enc_mae_supported == B_FALSE) {
+		rc = ENOTSUP;
+		goto fail1;
+	}
+
+	if (encp->enc_mae_aset_v2_supported == B_FALSE) {
+		rc = ENOTSUP;
+		goto fail2;
+	}
+
+	req.emr_cmd = MC_CMD_MAE_MAC_ADDR_FREE;
+	req.emr_in_buf = payload;
+	req.emr_in_length = MC_CMD_MAE_MAC_ADDR_FREE_IN_LEN(1);
+	req.emr_out_buf = payload;
+	req.emr_out_length = MC_CMD_MAE_MAC_ADDR_FREE_OUT_LEN(1);
+
+	MCDI_IN_SET_DWORD(req, MAE_MAC_ADDR_FREE_IN_MAC_ID, mac_idp->id);
+
+	efx_mcdi_execute(enp, &req);
+
+	if (req.emr_rc != 0) {
+		rc = req.emr_rc;
+		goto fail3;
+	}
+
+	if (req.emr_out_length_used < MC_CMD_MAE_MAC_ADDR_FREE_OUT_LEN(1)) {
+		rc = EMSGSIZE;
+		goto fail4;
+	}
+
+	if (MCDI_OUT_DWORD(req, MAE_MAC_ADDR_FREE_OUT_FREED_MAC_ID) !=
+	    mac_idp->id) {
+		/* Firmware failed to remove the MAC address entry. */
+		rc = EAGAIN;
+		goto fail5;
+	}
+
+	return (0);
+
+fail5:
+	EFSYS_PROBE(fail5);
+fail4:
+	EFSYS_PROBE(fail4);
+fail3:
+	EFSYS_PROBE(fail3);
+fail2:
+	EFSYS_PROBE(fail2);
+fail1:
+	EFSYS_PROBE1(fail1, efx_rc_t, rc);
+	return (rc);
+}
+
+	__checkReturn			efx_rc_t
+efx_mae_action_set_fill_in_dst_mac_id(
+	__in				efx_mae_actions_t *spec,
+	__in				const efx_mae_mac_id_t *mac_idp)
+{
+	efx_rc_t rc;
+
+	if ((spec->ema_actions & (1U << EFX_MAE_ACTION_SET_DST_MAC)) == 0) {
+		/*
+		 * The caller has not intended to have this action originally,
+		 * hence, they cannot indicate the MAC address entry ID.
+		 */
+		rc = EINVAL;
+		goto fail1;
+	}
+
+	if (spec->ema_rsrc.emar_dst_mac_id.id != EFX_MAE_RSRC_ID_INVALID) {
+		/* An attempt to indicate the MAC address entry ID twice. */
+		rc = EINVAL;
+		goto fail2;
+	}
+
+	if (mac_idp->id == EFX_MAE_RSRC_ID_INVALID) {
+		rc = EINVAL;
+		goto fail3;
+	}
+
+	spec->ema_rsrc.emar_dst_mac_id.id = mac_idp->id;
+
+	return (0);
+
+fail3:
+	EFSYS_PROBE(fail3);
+fail2:
+	EFSYS_PROBE(fail2);
+fail1:
+	EFSYS_PROBE1(fail1, efx_rc_t, rc);
+	return (rc);
+}
+
+	__checkReturn			efx_rc_t
+efx_mae_action_set_fill_in_src_mac_id(
+	__in				efx_mae_actions_t *spec,
+	__in				const efx_mae_mac_id_t *mac_idp)
+{
+	efx_rc_t rc;
+
+	if ((spec->ema_actions & (1U << EFX_MAE_ACTION_SET_SRC_MAC)) == 0) {
+		/*
+		 * The caller has not intended to have this action originally,
+		 * hence, they cannot indicate the MAC address entry ID.
+		 */
+		rc = EINVAL;
+		goto fail1;
+	}
+
+	if (spec->ema_rsrc.emar_src_mac_id.id != EFX_MAE_RSRC_ID_INVALID) {
+		/* An attempt to indicate the MAC address entry ID twice. */
+		rc = EINVAL;
+		goto fail2;
+	}
+
+	if (mac_idp->id == EFX_MAE_RSRC_ID_INVALID) {
+		rc = EINVAL;
+		goto fail3;
+	}
+
+	spec->ema_rsrc.emar_src_mac_id.id = mac_idp->id;
+
+	return (0);
+
 fail3:
 	EFSYS_PROBE(fail3);
 fail2:
@@ -2538,16 +2804,28 @@ efx_mae_action_set_alloc(
 		goto fail1;
 	}
 
+	if ((spec->ema_actions & (1U << EFX_MAE_ACTION_SET_DST_MAC)) != 0 &&
+	    spec->ema_rsrc.emar_dst_mac_id.id == EFX_MAE_RSRC_ID_INVALID) {
+		rc = EINVAL;
+		goto fail2;
+	}
+
+	if ((spec->ema_actions & (1U << EFX_MAE_ACTION_SET_SRC_MAC)) != 0 &&
+	    spec->ema_rsrc.emar_src_mac_id.id == EFX_MAE_RSRC_ID_INVALID) {
+		rc = EINVAL;
+		goto fail3;
+	}
+
 	if ((spec->ema_actions & (1U << EFX_MAE_ACTION_ENCAP)) != 0 &&
 	    spec->ema_rsrc.emar_eh_id.id == EFX_MAE_RSRC_ID_INVALID) {
 		rc = EINVAL;
-		goto fail2;
+		goto fail4;
 	}
 
 	if (spec->ema_n_count_actions == 1 &&
 	    spec->ema_rsrc.emar_counter_id.id == EFX_MAE_RSRC_ID_INVALID) {
 		rc = EINVAL;
-		goto fail3;
+		goto fail5;
 	}
 
 	req.emr_cmd = MC_CMD_MAE_ACTION_SET_ALLOC;
@@ -2572,6 +2850,12 @@ efx_mae_action_set_alloc(
 	MCDI_IN_SET_DWORD_FIELD(req, MAE_ACTION_SET_ALLOC_IN_FLAGS,
 	    MAE_ACTION_SET_ALLOC_IN_VLAN_POP, spec->ema_n_vlan_tags_to_pop);
 
+	MCDI_IN_SET_DWORD(req, MAE_ACTION_SET_ALLOC_IN_DST_MAC_ID,
+	    spec->ema_rsrc.emar_dst_mac_id.id);
+
+	MCDI_IN_SET_DWORD(req, MAE_ACTION_SET_ALLOC_IN_SRC_MAC_ID,
+	    spec->ema_rsrc.emar_src_mac_id.id);
+
 	if ((spec->ema_actions & (1U << EFX_MAE_ACTION_DECR_IP_TTL)) != 0) {
 		MCDI_IN_SET_DWORD_FIELD(req, MAE_ACTION_SET_ALLOC_IN_FLAGS,
 		    MAE_ACTION_SET_ALLOC_IN_DO_DECR_IP_TTL, 1);
@@ -2623,33 +2907,32 @@ efx_mae_action_set_alloc(
 	MCDI_IN_SET_DWORD(req,
 	    MAE_ACTION_SET_ALLOC_IN_DELIVER, spec->ema_deliver_mport.sel);
 
-	MCDI_IN_SET_DWORD(req, MAE_ACTION_SET_ALLOC_IN_SRC_MAC_ID,
-	    MC_CMD_MAE_MAC_ADDR_ALLOC_OUT_MAC_ID_NULL);
-	MCDI_IN_SET_DWORD(req, MAE_ACTION_SET_ALLOC_IN_DST_MAC_ID,
-	    MC_CMD_MAE_MAC_ADDR_ALLOC_OUT_MAC_ID_NULL);
-
 	efx_mcdi_execute(enp, &req);
 
 	if (req.emr_rc != 0) {
 		rc = req.emr_rc;
-		goto fail4;
+		goto fail6;
 	}
 
 	if (req.emr_out_length_used < MC_CMD_MAE_ACTION_SET_ALLOC_OUT_LEN) {
 		rc = EMSGSIZE;
-		goto fail5;
+		goto fail7;
 	}
 
 	aset_id.id = MCDI_OUT_DWORD(req, MAE_ACTION_SET_ALLOC_OUT_AS_ID);
 	if (aset_id.id == EFX_MAE_RSRC_ID_INVALID) {
 		rc = ENOENT;
-		goto fail6;
+		goto fail8;
 	}
 
 	aset_idp->id = aset_id.id;
 
 	return (0);
 
+fail8:
+	EFSYS_PROBE(fail8);
+fail7:
+	EFSYS_PROBE(fail7);
 fail6:
 	EFSYS_PROBE(fail6);
 fail5:
diff --git a/drivers/common/sfc_efx/version.map b/drivers/common/sfc_efx/version.map
index 765ca39332..1471aad2c4 100644
--- a/drivers/common/sfc_efx/version.map
+++ b/drivers/common/sfc_efx/version.map
@@ -90,7 +90,9 @@ INTERNAL {
 	efx_mae_action_rule_remove;
 	efx_mae_action_set_alloc;
 	efx_mae_action_set_fill_in_counter_id;
+	efx_mae_action_set_fill_in_dst_mac_id;
 	efx_mae_action_set_fill_in_eh_id;
+	efx_mae_action_set_fill_in_src_mac_id;
 	efx_mae_action_set_free;
 	efx_mae_action_set_get_nb_count;
 	efx_mae_action_set_populate_count;
@@ -101,6 +103,8 @@ INTERNAL {
 	efx_mae_action_set_populate_encap;
 	efx_mae_action_set_populate_flag;
 	efx_mae_action_set_populate_mark;
+	efx_mae_action_set_populate_set_dst_mac;
+	efx_mae_action_set_populate_set_src_mac;
 	efx_mae_action_set_populate_vlan_pop;
 	efx_mae_action_set_populate_vlan_push;
 	efx_mae_action_set_spec_fini;
@@ -116,6 +120,8 @@ INTERNAL {
 	efx_mae_fini;
 	efx_mae_get_limits;
 	efx_mae_init;
+	efx_mae_mac_addr_alloc;
+	efx_mae_mac_addr_free;
 	efx_mae_match_spec_bit_set;
 	efx_mae_match_spec_field_set;
 	efx_mae_match_spec_fini;
-- 
2.30.2


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH 4/4] net/sfc: support MAC address edits in transfer flows
  2021-11-17 11:44 [PATCH 0/4] net/sfc: support MAC address edits in transfer flows Ivan Malov
                   ` (2 preceding siblings ...)
  2021-11-17 11:44 ` [PATCH 3/4] common/sfc_efx/base: support MAC address edit actions in MAE Ivan Malov
@ 2021-11-17 11:44 ` Ivan Malov
  2021-11-17 13:17 ` [PATCH 0/4] " Ferruh Yigit
  4 siblings, 0 replies; 6+ messages in thread
From: Ivan Malov @ 2021-11-17 11:44 UTC (permalink / raw)
  To: dev; +Cc: Andrew Rybchenko, Andy Moreton

These edits affect the outermost header in the current processing state
of the packet, which might have been decapsulated by prior action DECAP.

Signed-off-by: Ivan Malov <ivan.malov@oktetlabs.ru>
Reviewed-by: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>
Reviewed-by: Andy Moreton <amoreton@xilinx.com>
---
 doc/guides/nics/features/sfc.ini |   2 +
 doc/guides/nics/sfc_efx.rst      |   4 +
 drivers/net/sfc/sfc_mae.c        | 292 ++++++++++++++++++++++++++++++-
 drivers/net/sfc/sfc_mae.h        |  15 ++
 4 files changed, 310 insertions(+), 3 deletions(-)

diff --git a/doc/guides/nics/features/sfc.ini b/doc/guides/nics/features/sfc.ini
index 1ce2dc46ba..2e798b5ef5 100644
--- a/doc/guides/nics/features/sfc.ini
+++ b/doc/guides/nics/features/sfc.ini
@@ -79,6 +79,8 @@ port_representor     = Y
 represented_port     = Y
 queue                = Y
 rss                  = Y
+set_mac_dst          = Y
+set_mac_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 00b95a4f58..39c6e23d5b 100644
--- a/doc/guides/nics/sfc_efx.rst
+++ b/doc/guides/nics/sfc_efx.rst
@@ -234,6 +234,10 @@ Supported actions (***transfer*** rules):
 
 - OF_VLAN_SET_PCP
 
+- SET_MAC_DST
+
+- SET_MAC_SRC
+
 - OF_DEC_NW_TTL
 
 - DEC_TTL
diff --git a/drivers/net/sfc/sfc_mae.c b/drivers/net/sfc/sfc_mae.c
index b7a148afae..b34c9afd5b 100644
--- a/drivers/net/sfc/sfc_mae.c
+++ b/drivers/net/sfc/sfc_mae.c
@@ -290,6 +290,7 @@ sfc_mae_attach(struct sfc_adapter *sa)
 	}
 
 	TAILQ_INIT(&mae->outer_rules);
+	TAILQ_INIT(&mae->mac_addrs);
 	TAILQ_INIT(&mae->encap_headers);
 	TAILQ_INIT(&mae->action_sets);
 
@@ -506,6 +507,189 @@ sfc_mae_outer_rule_disable(struct sfc_adapter *sa,
 	--(fw_rsrc->refcnt);
 }
 
+static struct sfc_mae_mac_addr *
+sfc_mae_mac_addr_attach(struct sfc_adapter *sa,
+			const uint8_t addr_bytes[EFX_MAC_ADDR_LEN])
+{
+	struct sfc_mae_mac_addr *mac_addr;
+	struct sfc_mae *mae = &sa->mae;
+
+	SFC_ASSERT(sfc_adapter_is_locked(sa));
+
+	TAILQ_FOREACH(mac_addr, &mae->mac_addrs, entries) {
+		if (memcmp(mac_addr->addr_bytes, addr_bytes,
+			   EFX_MAC_ADDR_LEN) == 0) {
+			sfc_dbg(sa, "attaching to mac_addr=%p", mac_addr);
+			++(mac_addr->refcnt);
+			return mac_addr;
+		}
+	}
+
+	return NULL;
+}
+
+static int
+sfc_mae_mac_addr_add(struct sfc_adapter *sa,
+		     const uint8_t addr_bytes[EFX_MAC_ADDR_LEN],
+		     struct sfc_mae_mac_addr **mac_addrp)
+{
+	struct sfc_mae_mac_addr *mac_addr;
+	struct sfc_mae *mae = &sa->mae;
+
+	SFC_ASSERT(sfc_adapter_is_locked(sa));
+
+	mac_addr = rte_zmalloc("sfc_mae_mac_addr", sizeof(*mac_addr), 0);
+	if (mac_addr == NULL)
+		return ENOMEM;
+
+	rte_memcpy(mac_addr->addr_bytes, addr_bytes, EFX_MAC_ADDR_LEN);
+
+	mac_addr->refcnt = 1;
+	mac_addr->fw_rsrc.mac_id.id = EFX_MAE_RSRC_ID_INVALID;
+
+	TAILQ_INSERT_TAIL(&mae->mac_addrs, mac_addr, entries);
+
+	*mac_addrp = mac_addr;
+
+	sfc_dbg(sa, "added mac_addr=%p", mac_addr);
+
+	return 0;
+}
+
+static void
+sfc_mae_mac_addr_del(struct sfc_adapter *sa, struct sfc_mae_mac_addr *mac_addr)
+{
+	struct sfc_mae *mae = &sa->mae;
+
+	if (mac_addr == NULL)
+		return;
+
+	SFC_ASSERT(sfc_adapter_is_locked(sa));
+	SFC_ASSERT(mac_addr->refcnt != 0);
+
+	--(mac_addr->refcnt);
+
+	if (mac_addr->refcnt != 0)
+		return;
+
+	if (mac_addr->fw_rsrc.mac_id.id != EFX_MAE_RSRC_ID_INVALID ||
+	    mac_addr->fw_rsrc.refcnt != 0) {
+		sfc_err(sa, "deleting mac_addr=%p abandons its FW resource: MAC_ID=0x%08x, refcnt=%u",
+			mac_addr, mac_addr->fw_rsrc.mac_id.id,
+			mac_addr->fw_rsrc.refcnt);
+	}
+
+	TAILQ_REMOVE(&mae->mac_addrs, mac_addr, entries);
+	rte_free(mac_addr);
+
+	sfc_dbg(sa, "deleted mac_addr=%p", mac_addr);
+}
+
+enum sfc_mae_mac_addr_type {
+	SFC_MAE_MAC_ADDR_DST,
+	SFC_MAE_MAC_ADDR_SRC
+};
+
+static int
+sfc_mae_mac_addr_enable(struct sfc_adapter *sa,
+			struct sfc_mae_mac_addr *mac_addr,
+			enum sfc_mae_mac_addr_type type,
+			efx_mae_actions_t *aset_spec)
+{
+	struct sfc_mae_fw_rsrc *fw_rsrc;
+	int rc = 0;
+
+	if (mac_addr == NULL)
+		return 0;
+
+	SFC_ASSERT(sfc_adapter_is_locked(sa));
+
+	fw_rsrc = &mac_addr->fw_rsrc;
+
+	if (fw_rsrc->refcnt == 0) {
+		SFC_ASSERT(fw_rsrc->mac_id.id == EFX_MAE_RSRC_ID_INVALID);
+
+		rc = efx_mae_mac_addr_alloc(sa->nic, mac_addr->addr_bytes,
+					    &fw_rsrc->mac_id);
+		if (rc != 0) {
+			sfc_err(sa, "failed to enable mac_addr=%p: %s",
+				mac_addr, strerror(rc));
+			return rc;
+		}
+	}
+
+	switch (type) {
+	case SFC_MAE_MAC_ADDR_DST:
+		rc = efx_mae_action_set_fill_in_dst_mac_id(aset_spec,
+							   &fw_rsrc->mac_id);
+		break;
+	case SFC_MAE_MAC_ADDR_SRC:
+		rc = efx_mae_action_set_fill_in_src_mac_id(aset_spec,
+							   &fw_rsrc->mac_id);
+		break;
+	default:
+		rc = EINVAL;
+		break;
+	}
+
+	if (rc != 0) {
+		if (fw_rsrc->refcnt == 0) {
+			(void)efx_mae_mac_addr_free(sa->nic, &fw_rsrc->mac_id);
+			fw_rsrc->mac_id.id = EFX_MAE_RSRC_ID_INVALID;
+		}
+
+		sfc_err(sa, "cannot fill in MAC address entry ID: %s",
+			strerror(rc));
+
+		return rc;
+	}
+
+	if (fw_rsrc->refcnt == 0) {
+		sfc_dbg(sa, "enabled mac_addr=%p: MAC_ID=0x%08x",
+			mac_addr, fw_rsrc->mac_id.id);
+	}
+
+	++(fw_rsrc->refcnt);
+
+	return 0;
+}
+
+static void
+sfc_mae_mac_addr_disable(struct sfc_adapter *sa,
+			 struct sfc_mae_mac_addr *mac_addr)
+{
+	struct sfc_mae_fw_rsrc *fw_rsrc;
+	int rc;
+
+	if (mac_addr == NULL)
+		return;
+
+	SFC_ASSERT(sfc_adapter_is_locked(sa));
+
+	fw_rsrc = &mac_addr->fw_rsrc;
+
+	if (fw_rsrc->mac_id.id == EFX_MAE_RSRC_ID_INVALID ||
+	    fw_rsrc->refcnt == 0) {
+		sfc_err(sa, "failed to disable mac_addr=%p: already disabled; MAC_ID=0x%08x, refcnt=%u",
+			mac_addr, fw_rsrc->mac_id.id, fw_rsrc->refcnt);
+		return;
+	}
+
+	if (fw_rsrc->refcnt == 1) {
+		rc = efx_mae_mac_addr_free(sa->nic, &fw_rsrc->mac_id);
+		if (rc == 0) {
+			sfc_dbg(sa, "disabled mac_addr=%p with MAC_ID=0x%08x",
+				mac_addr, fw_rsrc->mac_id.id);
+		} else {
+			sfc_err(sa, "failed to disable mac_addr=%p with MAC_ID=0x%08x: %s",
+				mac_addr, fw_rsrc->mac_id.id, strerror(rc));
+		}
+		fw_rsrc->mac_id.id = EFX_MAE_RSRC_ID_INVALID;
+	}
+
+	--(fw_rsrc->refcnt);
+}
+
 static struct sfc_mae_encap_header *
 sfc_mae_encap_header_attach(struct sfc_adapter *sa,
 			    const struct sfc_mae_bounce_eh *bounce_eh)
@@ -757,6 +941,8 @@ struct sfc_mae_aset_ctx {
 	struct sfc_mae_encap_header	*encap_header;
 	struct sfc_flow_tunnel		*counter_ft;
 	unsigned int			n_counters;
+	struct sfc_mae_mac_addr		*dst_mac;
+	struct sfc_mae_mac_addr		*src_mac;
 
 	efx_mae_actions_t		*spec;
 };
@@ -779,6 +965,8 @@ sfc_mae_action_set_attach(struct sfc_adapter *sa,
 
 	TAILQ_FOREACH(action_set, &mae->action_sets, entries) {
 		if (action_set->encap_header == ctx->encap_header &&
+		    action_set->dst_mac_addr == ctx->dst_mac &&
+		    action_set->src_mac_addr == ctx->src_mac &&
 		    efx_mae_action_set_specs_equal(action_set->spec,
 						   ctx->spec)) {
 			sfc_dbg(sa, "attaching to action_set=%p", action_set);
@@ -849,6 +1037,8 @@ sfc_mae_action_set_add(struct sfc_adapter *sa,
 	action_set->refcnt = 1;
 	action_set->spec = ctx->spec;
 	action_set->encap_header = ctx->encap_header;
+	action_set->dst_mac_addr = ctx->dst_mac;
+	action_set->src_mac_addr = ctx->src_mac;
 
 	action_set->fw_rsrc.aset_id.id = EFX_MAE_RSRC_ID_INVALID;
 
@@ -884,6 +1074,8 @@ sfc_mae_action_set_del(struct sfc_adapter *sa,
 
 	efx_mae_action_set_spec_fini(sa->nic, action_set->spec);
 	sfc_mae_encap_header_del(sa, action_set->encap_header);
+	sfc_mae_mac_addr_del(sa, action_set->dst_mac_addr);
+	sfc_mae_mac_addr_del(sa, action_set->src_mac_addr);
 	if (action_set->n_counters > 0) {
 		SFC_ASSERT(action_set->n_counters == 1);
 		SFC_ASSERT(action_set->counters[0].mae_id.id ==
@@ -901,6 +1093,8 @@ sfc_mae_action_set_enable(struct sfc_adapter *sa,
 			  struct sfc_mae_action_set *action_set)
 {
 	struct sfc_mae_encap_header *encap_header = action_set->encap_header;
+	struct sfc_mae_mac_addr *dst_mac_addr = action_set->dst_mac_addr;
+	struct sfc_mae_mac_addr *src_mac_addr = action_set->src_mac_addr;
 	struct sfc_mae_counter_id *counters = action_set->counters;
 	struct sfc_mae_fw_rsrc *fw_rsrc = &action_set->fw_rsrc;
 	int rc;
@@ -911,10 +1105,27 @@ sfc_mae_action_set_enable(struct sfc_adapter *sa,
 		SFC_ASSERT(fw_rsrc->aset_id.id == EFX_MAE_RSRC_ID_INVALID);
 		SFC_ASSERT(action_set->spec != NULL);
 
+		rc = sfc_mae_mac_addr_enable(sa, dst_mac_addr,
+					     SFC_MAE_MAC_ADDR_DST,
+					     action_set->spec);
+		if (rc != 0)
+			return rc;
+
+		rc = sfc_mae_mac_addr_enable(sa, src_mac_addr,
+					     SFC_MAE_MAC_ADDR_SRC,
+					     action_set->spec);
+		if (rc != 0) {
+			sfc_mae_mac_addr_disable(sa, dst_mac_addr);
+			return rc;
+		}
+
 		rc = sfc_mae_encap_header_enable(sa, encap_header,
 						 action_set->spec);
-		if (rc != 0)
+		if (rc != 0) {
+			sfc_mae_mac_addr_disable(sa, src_mac_addr);
+			sfc_mae_mac_addr_disable(sa, dst_mac_addr);
 			return rc;
+		}
 
 		rc = sfc_mae_counters_enable(sa, counters,
 					     action_set->n_counters,
@@ -924,6 +1135,8 @@ sfc_mae_action_set_enable(struct sfc_adapter *sa,
 				action_set->n_counters, rte_strerror(rc));
 
 			sfc_mae_encap_header_disable(sa, encap_header);
+			sfc_mae_mac_addr_disable(sa, src_mac_addr);
+			sfc_mae_mac_addr_disable(sa, dst_mac_addr);
 			return rc;
 		}
 
@@ -936,6 +1149,8 @@ sfc_mae_action_set_enable(struct sfc_adapter *sa,
 			(void)sfc_mae_counters_disable(sa, counters,
 						       action_set->n_counters);
 			sfc_mae_encap_header_disable(sa, encap_header);
+			sfc_mae_mac_addr_disable(sa, src_mac_addr);
+			sfc_mae_mac_addr_disable(sa, dst_mac_addr);
 			return rc;
 		}
 
@@ -983,6 +1198,8 @@ sfc_mae_action_set_disable(struct sfc_adapter *sa,
 		}
 
 		sfc_mae_encap_header_disable(sa, action_set->encap_header);
+		sfc_mae_mac_addr_disable(sa, action_set->src_mac_addr);
+		sfc_mae_mac_addr_disable(sa, action_set->dst_mac_addr);
 	}
 
 	--(fw_rsrc->refcnt);
@@ -2895,6 +3112,54 @@ sfc_mae_rule_parse_pattern(struct sfc_adapter *sa,
 	return rc;
 }
 
+static int
+sfc_mae_rule_parse_action_set_mac(struct sfc_adapter *sa,
+				  enum sfc_mae_mac_addr_type type,
+				  const struct rte_flow_action_set_mac *conf,
+				  struct sfc_mae_aset_ctx *ctx,
+				  struct rte_flow_error *error)
+{
+	struct sfc_mae_mac_addr **mac_addrp;
+	int rc;
+
+	if (conf == NULL) {
+		return rte_flow_error_set(error, EINVAL,
+				RTE_FLOW_ERROR_TYPE_ACTION_CONF, NULL,
+				"the MAC address entry definition is NULL");
+	}
+
+	switch (type) {
+	case SFC_MAE_MAC_ADDR_DST:
+		rc = efx_mae_action_set_populate_set_dst_mac(ctx->spec);
+		mac_addrp = &ctx->dst_mac;
+		break;
+	case SFC_MAE_MAC_ADDR_SRC:
+		rc = efx_mae_action_set_populate_set_src_mac(ctx->spec);
+		mac_addrp = &ctx->src_mac;
+		break;
+	default:
+		rc = EINVAL;
+		break;
+	}
+
+	if (rc != 0)
+		goto error;
+
+	*mac_addrp = sfc_mae_mac_addr_attach(sa, conf->mac_addr);
+	if (*mac_addrp != NULL)
+		return 0;
+
+	rc = sfc_mae_mac_addr_add(sa, conf->mac_addr, mac_addrp);
+	if (rc != 0)
+		goto error;
+
+	return 0;
+
+error:
+	return rte_flow_error_set(error, rc, RTE_FLOW_ERROR_TYPE_ACTION,
+				  NULL, "failed to request set MAC action");
+}
+
 /*
  * An action supported by MAE may correspond to a bundle of RTE flow actions,
  * in example, VLAN_PUSH = OF_PUSH_VLAN + OF_VLAN_SET_VID + OF_VLAN_SET_PCP.
@@ -3549,6 +3814,8 @@ sfc_mae_rule_parse_action_represented_port(struct sfc_adapter *sa,
 static const char * const action_names[] = {
 	[RTE_FLOW_ACTION_TYPE_VXLAN_DECAP] = "VXLAN_DECAP",
 	[RTE_FLOW_ACTION_TYPE_OF_POP_VLAN] = "OF_POP_VLAN",
+	[RTE_FLOW_ACTION_TYPE_SET_MAC_DST] = "SET_MAC_DST",
+	[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_OF_PUSH_VLAN] = "OF_PUSH_VLAN",
@@ -3573,11 +3840,12 @@ sfc_mae_rule_parse_action(struct sfc_adapter *sa,
 			  const struct rte_flow_action *action,
 			  const struct sfc_flow_spec_mae *spec_mae,
 			  struct sfc_mae_actions_bundle *bundle,
-			  efx_mae_actions_t *spec,
+			  struct sfc_mae_aset_ctx *ctx,
 			  struct rte_flow_error *error)
 {
 	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;
 	bool custom_error = B_FALSE;
 	int rc = 0;
 
@@ -3596,6 +3864,22 @@ sfc_mae_rule_parse_action(struct sfc_adapter *sa,
 				       bundle->actions_mask);
 		rc = efx_mae_action_set_populate_vlan_pop(spec);
 		break;
+	case RTE_FLOW_ACTION_TYPE_SET_MAC_DST:
+		SFC_BUILD_SET_OVERFLOW(RTE_FLOW_ACTION_TYPE_SET_MAC_DST,
+				       bundle->actions_mask);
+		rc = sfc_mae_rule_parse_action_set_mac(sa, SFC_MAE_MAC_ADDR_DST,
+						       action->conf, ctx,
+						       error);
+		custom_error = B_TRUE;
+		break;
+	case RTE_FLOW_ACTION_TYPE_SET_MAC_SRC:
+		SFC_BUILD_SET_OVERFLOW(RTE_FLOW_ACTION_TYPE_SET_MAC_SRC,
+				       bundle->actions_mask);
+		rc = sfc_mae_rule_parse_action_set_mac(sa, SFC_MAE_MAC_ADDR_SRC,
+						       action->conf, ctx,
+						       error);
+		custom_error = B_TRUE;
+		break;
 	case RTE_FLOW_ACTION_TYPE_OF_DEC_NW_TTL:
 	case RTE_FLOW_ACTION_TYPE_DEC_TTL:
 		SFC_BUILD_SET_OVERFLOW(RTE_FLOW_ACTION_TYPE_OF_DEC_NW_TTL,
@@ -3813,7 +4097,7 @@ sfc_mae_rule_parse_actions(struct sfc_adapter *sa,
 			goto fail_rule_parse_action;
 
 		rc = sfc_mae_rule_parse_action(sa, action, spec_mae,
-					       &bundle, ctx.spec, error);
+					       &bundle, &ctx, error);
 		if (rc != 0)
 			goto fail_rule_parse_action;
 	}
@@ -3880,6 +4164,8 @@ sfc_mae_rule_parse_actions(struct sfc_adapter *sa,
 
 fail_process_encap_header:
 fail_rule_parse_action:
+	sfc_mae_mac_addr_del(sa, ctx.src_mac);
+	sfc_mae_mac_addr_del(sa, ctx.dst_mac);
 	efx_mae_action_set_spec_fini(sa->nic, ctx.spec);
 
 fail_enforce_ft_count:
diff --git a/drivers/net/sfc/sfc_mae.h b/drivers/net/sfc/sfc_mae.h
index 2750fbb9b1..3431aaa734 100644
--- a/drivers/net/sfc/sfc_mae.h
+++ b/drivers/net/sfc/sfc_mae.h
@@ -29,6 +29,7 @@ struct sfc_mae_fw_rsrc {
 	union {
 		efx_mae_aset_id_t	aset_id;
 		efx_mae_rule_id_t	rule_id;
+		efx_mae_mac_id_t	mac_id;
 		efx_mae_eh_id_t		eh_id;
 	};
 };
@@ -44,6 +45,16 @@ struct sfc_mae_outer_rule {
 
 TAILQ_HEAD(sfc_mae_outer_rules, sfc_mae_outer_rule);
 
+/** MAC address registry entry */
+struct sfc_mae_mac_addr {
+	TAILQ_ENTRY(sfc_mae_mac_addr)	entries;
+	unsigned int			refcnt;
+	uint8_t				addr_bytes[EFX_MAC_ADDR_LEN];
+	struct sfc_mae_fw_rsrc		fw_rsrc;
+};
+
+TAILQ_HEAD(sfc_mae_mac_addrs, sfc_mae_mac_addr);
+
 /** Encap. header registry entry */
 struct sfc_mae_encap_header {
 	TAILQ_ENTRY(sfc_mae_encap_header)	entries;
@@ -79,6 +90,8 @@ struct sfc_mae_action_set {
 	uint32_t			n_counters;
 	efx_mae_actions_t		*spec;
 	struct sfc_mae_encap_header	*encap_header;
+	struct sfc_mae_mac_addr		*dst_mac_addr;
+	struct sfc_mae_mac_addr		*src_mac_addr;
 	struct sfc_mae_fw_rsrc		fw_rsrc;
 };
 
@@ -211,6 +224,8 @@ struct sfc_mae {
 	struct sfc_mae_outer_rules	outer_rules;
 	/** Encap. header registry */
 	struct sfc_mae_encap_headers	encap_headers;
+	/** MAC address registry */
+	struct sfc_mae_mac_addrs	mac_addrs;
 	/** Action set registry */
 	struct sfc_mae_action_sets	action_sets;
 	/** Encap. header bounce buffer */
-- 
2.30.2


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH 0/4] net/sfc: support MAC address edits in transfer flows
  2021-11-17 11:44 [PATCH 0/4] net/sfc: support MAC address edits in transfer flows Ivan Malov
                   ` (3 preceding siblings ...)
  2021-11-17 11:44 ` [PATCH 4/4] net/sfc: support MAC address edits in transfer flows Ivan Malov
@ 2021-11-17 13:17 ` Ferruh Yigit
  4 siblings, 0 replies; 6+ messages in thread
From: Ferruh Yigit @ 2021-11-17 13:17 UTC (permalink / raw)
  To: Ivan Malov; +Cc: dev

On 11/17/2021 11:44 AM, Ivan Malov wrote:
> Ivan Malov (4):
>    net/sfc: refine the order of checks on MAE action set attach
>    net/sfc: organise MAE flow action parsing function arguments
>    common/sfc_efx/base: support MAC address edit actions in MAE
>    net/sfc: support MAC address edits in transfer flows
> 

Series applied to dpdk-next-net/main, thanks.

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2021-11-17 13:17 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-11-17 11:44 [PATCH 0/4] net/sfc: support MAC address edits in transfer flows Ivan Malov
2021-11-17 11:44 ` [PATCH 1/4] net/sfc: refine the order of checks on MAE action set attach Ivan Malov
2021-11-17 11:44 ` [PATCH 2/4] net/sfc: organise MAE flow action parsing function arguments Ivan Malov
2021-11-17 11:44 ` [PATCH 3/4] common/sfc_efx/base: support MAC address edit actions in MAE Ivan Malov
2021-11-17 11:44 ` [PATCH 4/4] net/sfc: support MAC address edits in transfer flows Ivan Malov
2021-11-17 13:17 ` [PATCH 0/4] " Ferruh Yigit

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).