[v4,15/34] net/sfc: extend generic flow API to allow for internal flows

Message ID 20230607130245.8048-16-ivan.malov@arknetworks.am (mailing list archive)
State Accepted, archived
Delegated to: Ferruh Yigit
Headers
Series net/sfc: support HW conntrack assistance |

Checks

Context Check Description
ci/checkpatch success coding style OK

Commit Message

Ivan Malov June 7, 2023, 1:02 p.m. UTC
  At the moment, driver-internal flow rules are provisioned by
functions that are separate from the generic flow management
framework. In order to use the latter for such rules, extend
it accordingly. This will be actually used in the next patch.

Signed-off-by: Ivan Malov <ivan.malov@arknetworks.am>
Reviewed-by: Andy Moreton <amoreton@xilinx.com>
---
 drivers/net/sfc/sfc.c      |  9 ++++-----
 drivers/net/sfc/sfc_flow.c | 37 +++++++++++++++++++++++++++----------
 drivers/net/sfc/sfc_flow.h |  5 ++++-
 drivers/net/sfc/sfc_mae.c  | 31 +++++++++++++++++++++++++++----
 drivers/net/sfc/sfc_mae.h  |  5 +++--
 5 files changed, 65 insertions(+), 22 deletions(-)
  

Patch

diff --git a/drivers/net/sfc/sfc.c b/drivers/net/sfc/sfc.c
index a56521696a..2cfff20f47 100644
--- a/drivers/net/sfc/sfc.c
+++ b/drivers/net/sfc/sfc.c
@@ -975,6 +975,8 @@  sfc_attach(struct sfc_adapter *sa)
 	if (rc != 0)
 		goto fail_rss_attach;
 
+	sfc_flow_init(sa);
+
 	rc = sfc_flow_rss_attach(sa);
 	if (rc != 0)
 		goto fail_flow_rss_attach;
@@ -1006,8 +1008,6 @@  sfc_attach(struct sfc_adapter *sa)
 	sfc_log_init(sa, "fini nic");
 	efx_nic_fini(enp);
 
-	sfc_flow_init(sa);
-
 	rc = sfc_sw_xstats_init(sa);
 	if (rc != 0)
 		goto fail_sw_xstats_init;
@@ -1030,7 +1030,6 @@  sfc_attach(struct sfc_adapter *sa)
 	sfc_sw_xstats_close(sa);
 
 fail_sw_xstats_init:
-	sfc_flow_fini(sa);
 	sfc_repr_proxy_detach(sa);
 
 fail_repr_proxy_attach:
@@ -1052,6 +1051,7 @@  sfc_attach(struct sfc_adapter *sa)
 	sfc_flow_rss_detach(sa);
 
 fail_flow_rss_attach:
+	sfc_flow_fini(sa);
 	sfc_rss_detach(sa);
 
 fail_rss_attach:
@@ -1099,8 +1099,6 @@  sfc_detach(struct sfc_adapter *sa)
 
 	sfc_sriov_vswitch_destroy(sa);
 
-	sfc_flow_fini(sa);
-
 	sfc_repr_proxy_detach(sa);
 	sfc_mae_switchdev_fini(sa);
 	sfc_tbls_detach(sa);
@@ -1108,6 +1106,7 @@  sfc_detach(struct sfc_adapter *sa)
 	sfc_mae_counter_rxq_detach(sa);
 	sfc_filter_detach(sa);
 	sfc_flow_rss_detach(sa);
+	sfc_flow_fini(sa);
 	sfc_rss_detach(sa);
 	sfc_port_detach(sa);
 	sfc_ev_detach(sa);
diff --git a/drivers/net/sfc/sfc_flow.c b/drivers/net/sfc/sfc_flow.c
index 432295ea62..f6d1ae2a5b 100644
--- a/drivers/net/sfc/sfc_flow.c
+++ b/drivers/net/sfc/sfc_flow.c
@@ -7,6 +7,8 @@ 
  * for Solarflare) and Solarflare Communications, Inc.
  */
 
+#include <stdbool.h>
+
 #include <rte_byteorder.h>
 #include <rte_tailq.h>
 #include <rte_common.h>
@@ -2405,7 +2407,7 @@  sfc_flow_parse_rte_to_mae(struct rte_eth_dev *dev,
 	if (rc != 0)
 		goto fail;
 
-	rc = sfc_mae_rule_parse_pattern(sa, pattern, spec_mae, error);
+	rc = sfc_mae_rule_parse_pattern(sa, pattern, flow, error);
 	if (rc != 0)
 		goto fail;
 
@@ -2421,7 +2423,7 @@  sfc_flow_parse_rte_to_mae(struct rte_eth_dev *dev,
 		 */
 	}
 
-	rc = sfc_mae_rule_parse_actions(sa, actions, spec_mae, error);
+	rc = sfc_mae_rule_parse_actions(sa, actions, flow, error);
 	if (rc != 0)
 		goto fail;
 
@@ -2613,14 +2615,14 @@  sfc_flow_create(struct rte_eth_dev *dev,
 	struct rte_flow *flow;
 
 	sfc_adapter_lock(sa);
-	flow = sfc_flow_create_locked(sa, attr, pattern, actions, error);
+	flow = sfc_flow_create_locked(sa, false, attr, pattern, actions, error);
 	sfc_adapter_unlock(sa);
 
 	return flow;
 }
 
 struct rte_flow *
-sfc_flow_create_locked(struct sfc_adapter *sa,
+sfc_flow_create_locked(struct sfc_adapter *sa, bool internal,
 		       const struct rte_flow_attr *attr,
 		       const struct rte_flow_item pattern[],
 		       const struct rte_flow_action actions[],
@@ -2635,13 +2637,15 @@  sfc_flow_create_locked(struct sfc_adapter *sa,
 	if (flow == NULL)
 		goto fail_no_mem;
 
+	flow->internal = internal;
+
 	rc = sfc_flow_parse(sa->eth_dev, attr, pattern, actions, flow, error);
 	if (rc != 0)
 		goto fail_bad_value;
 
 	TAILQ_INSERT_TAIL(&sa->flow_list, flow, entries);
 
-	if (sa->state == SFC_ETHDEV_STARTED) {
+	if (flow->internal || sa->state == SFC_ETHDEV_STARTED) {
 		rc = sfc_flow_insert(sa, flow, error);
 		if (rc != 0)
 			goto fail_flow_insert;
@@ -2694,7 +2698,7 @@  sfc_flow_destroy_locked(struct sfc_adapter *sa, struct rte_flow *flow,
 		goto fail_bad_value;
 	}
 
-	if (sa->state == SFC_ETHDEV_STARTED)
+	if (flow->internal || sa->state == SFC_ETHDEV_STARTED)
 		rc = sfc_flow_remove(sa, flow, error);
 
 	TAILQ_REMOVE(&sa->flow_list, flow, entries);
@@ -2711,10 +2715,14 @@  sfc_flow_flush(struct rte_eth_dev *dev,
 	struct sfc_adapter *sa = sfc_adapter_by_eth_dev(dev);
 	struct rte_flow *flow;
 	int ret = 0;
+	void *tmp;
 
 	sfc_adapter_lock(sa);
 
-	while ((flow = TAILQ_FIRST(&sa->flow_list)) != NULL) {
+	RTE_TAILQ_FOREACH_SAFE(flow, &sa->flow_list, entries, tmp) {
+		if (flow->internal)
+			continue;
+
 		if (sa->state == SFC_ETHDEV_STARTED) {
 			int rc;
 
@@ -2842,10 +2850,14 @@  void
 sfc_flow_fini(struct sfc_adapter *sa)
 {
 	struct rte_flow *flow;
+	void *tmp;
 
 	SFC_ASSERT(sfc_adapter_is_locked(sa));
 
-	while ((flow = TAILQ_FIRST(&sa->flow_list)) != NULL) {
+	RTE_TAILQ_FOREACH_SAFE(flow, &sa->flow_list, entries, tmp) {
+		if (flow->internal)
+			continue;
+
 		TAILQ_REMOVE(&sa->flow_list, flow, entries);
 		sfc_flow_free(sa, flow);
 	}
@@ -2858,8 +2870,10 @@  sfc_flow_stop(struct sfc_adapter *sa)
 
 	SFC_ASSERT(sfc_adapter_is_locked(sa));
 
-	TAILQ_FOREACH(flow, &sa->flow_list, entries)
-		sfc_flow_remove(sa, flow, NULL);
+	TAILQ_FOREACH(flow, &sa->flow_list, entries) {
+		if (!flow->internal)
+			sfc_flow_remove(sa, flow, NULL);
+	}
 
 	/*
 	 * MAE counter service is not stopped on flow rule remove to avoid
@@ -2881,6 +2895,9 @@  sfc_flow_start(struct sfc_adapter *sa)
 	sfc_ft_counters_reset(sa);
 
 	TAILQ_FOREACH(flow, &sa->flow_list, entries) {
+		if (flow->internal)
+			continue;
+
 		rc = sfc_flow_insert(sa, flow, NULL);
 		if (rc != 0)
 			goto fail_bad_flow;
diff --git a/drivers/net/sfc/sfc_flow.h b/drivers/net/sfc/sfc_flow.h
index a3ca09f225..ec5e29f257 100644
--- a/drivers/net/sfc/sfc_flow.h
+++ b/drivers/net/sfc/sfc_flow.h
@@ -10,6 +10,8 @@ 
 #ifndef _SFC_FLOW_H
 #define _SFC_FLOW_H
 
+#include <stdbool.h>
+
 #include <rte_tailq.h>
 #include <rte_flow_driver.h>
 
@@ -101,6 +103,7 @@  struct sfc_flow_spec {
 struct rte_flow {
 	struct sfc_flow_spec spec;	/* flow specification */
 	TAILQ_ENTRY(rte_flow) entries;	/* flow list entries */
+	bool internal;			/* true for internal rules */
 };
 
 TAILQ_HEAD(sfc_flow_list, rte_flow);
@@ -195,7 +198,7 @@  typedef int (sfc_flow_query_cb_t)(struct rte_eth_dev *dev,
 				  void *data,
 				  struct rte_flow_error *error);
 
-struct rte_flow *sfc_flow_create_locked(struct sfc_adapter *sa,
+struct rte_flow *sfc_flow_create_locked(struct sfc_adapter *sa, bool internal,
 					const struct rte_flow_attr *attr,
 					const struct rte_flow_item pattern[],
 					const struct rte_flow_action actions[],
diff --git a/drivers/net/sfc/sfc_mae.c b/drivers/net/sfc/sfc_mae.c
index 89fa75281f..f7bf682c11 100644
--- a/drivers/net/sfc/sfc_mae.c
+++ b/drivers/net/sfc/sfc_mae.c
@@ -2537,6 +2537,20 @@  sfc_mae_rule_process_outer(struct sfc_adapter *sa,
 	efx_mae_rule_id_t invalid_rule_id = { .id = EFX_MAE_RSRC_ID_INVALID };
 	int rc;
 
+	if (ctx->internal) {
+		/*
+		 * A driver-internal flow may not comprise an outer rule,
+		 * but it must not match on invalid outer rule ID since
+		 * it must catch all missed packets, including those
+		 * that hit an outer rule of another flow entry but
+		 * do not hit a higher-priority action rule later.
+		 * So do not set match on outer rule ID here.
+		 */
+		SFC_ASSERT(ctx->match_spec_outer == NULL);
+		*rulep = NULL;
+		return 0;
+	}
+
 	if (ctx->encap_type == EFX_TUNNEL_PROTOCOL_NONE) {
 		*rulep = NULL;
 		goto no_or_id;
@@ -2823,9 +2837,10 @@  sfc_mae_rule_encap_parse_fini(struct sfc_adapter *sa,
 int
 sfc_mae_rule_parse_pattern(struct sfc_adapter *sa,
 			   const struct rte_flow_item pattern[],
-			   struct sfc_flow_spec_mae *spec,
+			   struct rte_flow *flow,
 			   struct rte_flow_error *error)
 {
+	struct sfc_flow_spec_mae *spec = &flow->spec.mae;
 	struct sfc_mae_parse_ctx ctx_mae;
 	unsigned int priority_shift = 0;
 	struct sfc_flow_parse_ctx ctx;
@@ -2833,6 +2848,7 @@  sfc_mae_rule_parse_pattern(struct sfc_adapter *sa,
 
 	memset(&ctx_mae, 0, sizeof(ctx_mae));
 	ctx_mae.ft_rule_type = spec->ft_rule_type;
+	ctx_mae.internal = flow->internal;
 	ctx_mae.priority = spec->priority;
 	ctx_mae.ft_ctx = spec->ft_ctx;
 	ctx_mae.sa = sa;
@@ -3642,11 +3658,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 sfc_flow_spec_mae *spec_mae,
+			  const 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;
 	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;
@@ -3770,6 +3787,11 @@  sfc_mae_rule_parse_action(struct sfc_adapter *sa,
 
 		switch_port_type_mask = 1U << SFC_MAE_SWITCH_PORT_INDEPENDENT;
 
+		if (flow->internal) {
+			switch_port_type_mask |=
+					1U << SFC_MAE_SWITCH_PORT_REPRESENTOR;
+		}
+
 		rc = sfc_mae_rule_parse_action_port_representor(sa,
 				action->conf, switch_port_type_mask, spec);
 		break;
@@ -3840,9 +3862,10 @@  sfc_mae_process_encap_header(struct sfc_adapter *sa,
 int
 sfc_mae_rule_parse_actions(struct sfc_adapter *sa,
 			   const struct rte_flow_action actions[],
-			   struct sfc_flow_spec_mae *spec_mae,
+			   struct rte_flow *flow,
 			   struct rte_flow_error *error)
 {
+	struct sfc_flow_spec_mae *spec_mae = &flow->spec.mae;
 	struct sfc_mae_actions_bundle bundle = {0};
 	const struct rte_flow_action *action;
 	struct sfc_mae_aset_ctx ctx = {0};
@@ -3899,7 +3922,7 @@  sfc_mae_rule_parse_actions(struct sfc_adapter *sa,
 		if (rc != 0)
 			goto fail_rule_parse_action;
 
-		rc = sfc_mae_rule_parse_action(sa, action, spec_mae,
+		rc = sfc_mae_rule_parse_action(sa, action, flow,
 					       &bundle, &ctx, error);
 		if (rc != 0)
 			goto fail_rule_parse_action;
diff --git a/drivers/net/sfc/sfc_mae.h b/drivers/net/sfc/sfc_mae.h
index d2995ded88..307236ea11 100644
--- a/drivers/net/sfc/sfc_mae.h
+++ b/drivers/net/sfc/sfc_mae.h
@@ -363,6 +363,7 @@  struct sfc_mae_parse_ctx {
 	size_t				tunnel_def_mask_size;
 	const void			*tunnel_def_mask;
 	bool				match_mport_set;
+	bool				internal;
 	enum sfc_ft_rule_type		ft_rule_type;
 	struct sfc_mae_pattern_data	pattern_data;
 	efx_tunnel_protocol_t		encap_type;
@@ -376,11 +377,11 @@  void sfc_mae_detach(struct sfc_adapter *sa);
 sfc_flow_cleanup_cb_t sfc_mae_flow_cleanup;
 int sfc_mae_rule_parse_pattern(struct sfc_adapter *sa,
 			       const struct rte_flow_item pattern[],
-			       struct sfc_flow_spec_mae *spec,
+			       struct rte_flow *flow,
 			       struct rte_flow_error *error);
 int sfc_mae_rule_parse_actions(struct sfc_adapter *sa,
 			       const struct rte_flow_action actions[],
-			       struct sfc_flow_spec_mae *spec_mae,
+			       struct rte_flow *flow,
 			       struct rte_flow_error *error);
 sfc_flow_verify_cb_t sfc_mae_flow_verify;
 sfc_flow_insert_cb_t sfc_mae_flow_insert;