[v4,14/34] net/sfc: let driver-internal flows use VF representor action

Message ID 20230607130245.8048-15-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
  In the case of VF <--> VF representor pairs, these flows can
only collect VF traffic, so let them use generic flow action
PORT_REPRESENTOR, as part of re-using generic flow mechanism.

Currently, it does not allow to access VF representors since
they have no unique HW logical ports (m-ports). They all sit
on the same (representor proxy) m-port, while demultiplexing
of traffic uses ingress (VF) m-port value in packet metadata.
Traffic from arbitrary sources cannot be identified this way.
But, for VF traffic, it should be right to make an exception.

Signed-off-by: Ivan Malov <ivan.malov@arknetworks.am>
Reviewed-by: Andy Moreton <amoreton@xilinx.com>
---
 drivers/net/sfc/sfc_mae.c            | 25 +++++++++++++++++++------
 drivers/net/sfc/sfc_repr.c           | 20 ++++++++++++++++----
 drivers/net/sfc/sfc_repr_proxy.c     | 15 +++++++++++++++
 drivers/net/sfc/sfc_repr_proxy_api.h |  3 +++
 drivers/net/sfc/sfc_switch.c         |  7 ++-----
 drivers/net/sfc/sfc_switch.h         | 10 ++++++++++
 6 files changed, 65 insertions(+), 15 deletions(-)
  

Patch

diff --git a/drivers/net/sfc/sfc_mae.c b/drivers/net/sfc/sfc_mae.c
index 1928d58779..89fa75281f 100644
--- a/drivers/net/sfc/sfc_mae.c
+++ b/drivers/net/sfc/sfc_mae.c
@@ -1525,6 +1525,7 @@  sfc_mae_rule_parse_item_port_id(const struct rte_flow_item *item,
 	const struct rte_flow_item_port_id *spec = NULL;
 	const struct rte_flow_item_port_id *mask = NULL;
 	efx_mport_sel_t mport_sel;
+	unsigned int type_mask;
 	int rc;
 
 	if (ctx_mae->match_mport_set) {
@@ -1556,8 +1557,10 @@  sfc_mae_rule_parse_item_port_id(const struct rte_flow_item *item,
 					  "The port ID is too large");
 	}
 
+	type_mask = 1U << SFC_MAE_SWITCH_PORT_INDEPENDENT;
+
 	rc = sfc_mae_switch_get_ethdev_mport(ctx_mae->sa->mae.switch_domain_id,
-					     spec->id, &mport_sel);
+					     spec->id, type_mask, &mport_sel);
 	if (rc != 0) {
 		return rte_flow_error_set(error, rc,
 				RTE_FLOW_ERROR_TYPE_ITEM, item,
@@ -1590,6 +1593,7 @@  sfc_mae_rule_parse_item_ethdev_based(const struct rte_flow_item *item,
 	const struct rte_flow_item_ethdev *spec = NULL;
 	const struct rte_flow_item_ethdev *mask = NULL;
 	efx_mport_sel_t mport_sel;
+	unsigned int type_mask;
 	int rc;
 
 	if (ctx_mae->match_mport_set) {
@@ -1617,9 +1621,11 @@  sfc_mae_rule_parse_item_ethdev_based(const struct rte_flow_item *item,
 
 	switch (item->type) {
 	case RTE_FLOW_ITEM_TYPE_PORT_REPRESENTOR:
+		type_mask = 1U << SFC_MAE_SWITCH_PORT_INDEPENDENT;
+
 		rc = sfc_mae_switch_get_ethdev_mport(
 				ctx_mae->sa->mae.switch_domain_id,
-				spec->port_id, &mport_sel);
+				spec->port_id, type_mask, &mport_sel);
 		if (rc != 0) {
 			return rte_flow_error_set(error, rc,
 					RTE_FLOW_ERROR_TYPE_ITEM, item,
@@ -3529,6 +3535,7 @@  sfc_mae_rule_parse_action_port_id(struct sfc_adapter *sa,
 {
 	struct sfc_adapter_shared * const sas = sfc_sa2shared(sa);
 	struct sfc_mae *mae = &sa->mae;
+	unsigned int type_mask;
 	efx_mport_sel_t mport;
 	uint16_t port_id;
 	int rc;
@@ -3538,8 +3545,10 @@  sfc_mae_rule_parse_action_port_id(struct sfc_adapter *sa,
 
 	port_id = (conf->original != 0) ? sas->port_id : conf->id;
 
+	type_mask = 1U << SFC_MAE_SWITCH_PORT_INDEPENDENT;
+
 	rc = sfc_mae_switch_get_ethdev_mport(mae->switch_domain_id,
-					     port_id, &mport);
+					     port_id, type_mask, &mport);
 	if (rc != 0) {
 		sfc_err(sa, "failed to get m-port for the given ethdev (port_id=%u): %s",
 			port_id, strerror(rc));
@@ -3558,14 +3567,14 @@  sfc_mae_rule_parse_action_port_id(struct sfc_adapter *sa,
 static int
 sfc_mae_rule_parse_action_port_representor(struct sfc_adapter *sa,
 		const struct rte_flow_action_ethdev *conf,
-		efx_mae_actions_t *spec)
+		unsigned int type_mask, efx_mae_actions_t *spec)
 {
 	struct sfc_mae *mae = &sa->mae;
 	efx_mport_sel_t mport;
 	int rc;
 
 	rc = sfc_mae_switch_get_ethdev_mport(mae->switch_domain_id,
-					     conf->port_id, &mport);
+					     conf->port_id, type_mask, &mport);
 	if (rc != 0) {
 		sfc_err(sa, "failed to get m-port for the given ethdev (port_id=%u): %s",
 			conf->port_id, strerror(rc));
@@ -3641,6 +3650,7 @@  sfc_mae_rule_parse_action(struct sfc_adapter *sa,
 	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;
+	unsigned int switch_port_type_mask;
 	bool custom_error = B_FALSE;
 	int rc = 0;
 
@@ -3757,8 +3767,11 @@  sfc_mae_rule_parse_action(struct sfc_adapter *sa,
 	case RTE_FLOW_ACTION_TYPE_PORT_REPRESENTOR:
 		SFC_BUILD_SET_OVERFLOW(RTE_FLOW_ACTION_TYPE_PORT_REPRESENTOR,
 				       bundle->actions_mask);
+
+		switch_port_type_mask = 1U << SFC_MAE_SWITCH_PORT_INDEPENDENT;
+
 		rc = sfc_mae_rule_parse_action_port_representor(sa,
-				action->conf, spec);
+				action->conf, switch_port_type_mask, spec);
 		break;
 	case RTE_FLOW_ACTION_TYPE_REPRESENTED_PORT:
 		SFC_BUILD_SET_OVERFLOW(RTE_FLOW_ACTION_TYPE_REPRESENTED_PORT,
diff --git a/drivers/net/sfc/sfc_repr.c b/drivers/net/sfc/sfc_repr.c
index d4134ec91b..6c7727d569 100644
--- a/drivers/net/sfc/sfc_repr.c
+++ b/drivers/net/sfc/sfc_repr.c
@@ -933,15 +933,26 @@  sfc_repr_eth_dev_init(struct rte_eth_dev *dev, void *init_params)
 	struct sfc_repr_shared *srs = sfc_repr_shared_by_eth_dev(dev);
 	struct sfc_mae_switch_port_request switch_port_request;
 	efx_mport_sel_t ethdev_mport_sel;
+	efx_mport_id_t proxy_mport_id;
 	struct sfc_repr *sr;
 	int ret;
 
 	/*
-	 * Currently there is no mport we can use for representor's
-	 * ethdev. Use an invalid one for now. This way representors
-	 * can be instantiated.
+	 * For each representor, a driver-internal flow has to be installed
+	 * in order to direct traffic coming from the represented entity to
+	 * the "representor proxy". Such internal flows need to find ethdev
+	 * mport by ethdev ID of the representors in question to specify in
+	 * delivery action. So set the representor ethdev's mport to that
+	 * of the "representor proxy" in below switch port request.
 	 */
-	efx_mae_mport_invalid(&ethdev_mport_sel);
+	sfc_repr_proxy_mport_alias_get(repr_data->pf_port_id, &proxy_mport_id);
+
+	ret = efx_mae_mport_by_id(&proxy_mport_id, &ethdev_mport_sel);
+	if (ret != 0) {
+		SFC_GENERIC_LOG(ERR,
+			"%s() failed to get repr proxy mport by ID", __func__);
+		goto fail_get_selector;
+	}
 
 	memset(&switch_port_request, 0, sizeof(switch_port_request));
 	switch_port_request.type = SFC_MAE_SWITCH_PORT_REPRESENTOR;
@@ -1033,6 +1044,7 @@  sfc_repr_eth_dev_init(struct rte_eth_dev *dev, void *init_params)
 
 fail_create_port:
 fail_mae_assign_switch_port:
+fail_get_selector:
 	SFC_GENERIC_LOG(ERR, "%s() failed: %s", __func__, rte_strerror(-ret));
 	return ret;
 }
diff --git a/drivers/net/sfc/sfc_repr_proxy.c b/drivers/net/sfc/sfc_repr_proxy.c
index 4ba7683370..74c3494c35 100644
--- a/drivers/net/sfc/sfc_repr_proxy.c
+++ b/drivers/net/sfc/sfc_repr_proxy.c
@@ -1708,3 +1708,18 @@  sfc_repr_proxy_repr_entity_mac_addr_set(uint16_t pf_port_id, uint16_t repr_id,
 
 	return rc;
 }
+
+void
+sfc_repr_proxy_mport_alias_get(uint16_t pf_port_id, efx_mport_id_t *mport_alias)
+{
+	const struct sfc_repr_proxy *rp;
+	struct sfc_adapter *sa;
+
+	sa = sfc_get_adapter_by_pf_port_id(pf_port_id);
+	sfc_adapter_lock(sa);
+	rp = sfc_repr_proxy_by_adapter(sa);
+
+	memcpy(mport_alias, &rp->mport_alias, sizeof(*mport_alias));
+
+	sfc_adapter_unlock(sa);
+}
diff --git a/drivers/net/sfc/sfc_repr_proxy_api.h b/drivers/net/sfc/sfc_repr_proxy_api.h
index 1d38ab2451..07d79a50cb 100644
--- a/drivers/net/sfc/sfc_repr_proxy_api.h
+++ b/drivers/net/sfc/sfc_repr_proxy_api.h
@@ -46,6 +46,9 @@  int sfc_repr_proxy_stop_repr(uint16_t pf_port_id, uint16_t repr_id);
 int sfc_repr_proxy_repr_entity_mac_addr_set(uint16_t pf_port_id,
 		uint16_t repr_id, const struct rte_ether_addr *mac_addr);
 
+void sfc_repr_proxy_mport_alias_get(uint16_t pf_port_id,
+				    efx_mport_id_t *mport_alias);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/drivers/net/sfc/sfc_switch.c b/drivers/net/sfc/sfc_switch.c
index 8f1ee97fa8..f80de4e889 100644
--- a/drivers/net/sfc/sfc_switch.c
+++ b/drivers/net/sfc/sfc_switch.c
@@ -551,6 +551,7 @@  sfc_mae_find_switch_port_by_ethdev(uint16_t switch_domain_id,
 int
 sfc_mae_switch_get_ethdev_mport(uint16_t switch_domain_id,
 				uint16_t ethdev_port_id,
+				unsigned int allowed_mae_switch_port_types,
 				efx_mport_sel_t *mport_sel)
 {
 	struct sfc_mae_switch_port *port;
@@ -562,11 +563,7 @@  sfc_mae_switch_get_ethdev_mport(uint16_t switch_domain_id,
 	if (rc != 0)
 		goto unlock;
 
-	if (port->type != SFC_MAE_SWITCH_PORT_INDEPENDENT) {
-		/*
-		 * The ethdev is a "VF representor". It does not own
-		 * a dedicated m-port suitable for use in flow rules.
-		 */
+	if (((1U << port->type) & allowed_mae_switch_port_types) == 0) {
 		rc = ENOTSUP;
 		goto unlock;
 	}
diff --git a/drivers/net/sfc/sfc_switch.h b/drivers/net/sfc/sfc_switch.h
index 62aea9b785..6a85ce4dcf 100644
--- a/drivers/net/sfc/sfc_switch.h
+++ b/drivers/net/sfc/sfc_switch.h
@@ -102,8 +102,18 @@  int sfc_mae_assign_switch_port(uint16_t switch_domain_id,
 int sfc_mae_clear_switch_port(uint16_t switch_domain_id,
 			      uint16_t switch_port_id);
 
+/*
+ * For user flows, allowed_mae_switch_port_types can only contain bit
+ * SFC_MAE_SWITCH_PORT_INDEPENDENT, meaning that only those ethdevs
+ * that have their own MAE m-ports can be accessed by a port-based
+ * action. For driver-internal flows, this mask can also contain
+ * bit SFC_MAE_SWITCH_PORT_REPRESENTOR to allow VF traffic to be
+ * sent to the common MAE m-port of all such REPRESENTOR ports
+ * via a port-based action, for default switch interconnection.
+ */
 int sfc_mae_switch_get_ethdev_mport(uint16_t switch_domain_id,
 				    uint16_t ethdev_port_id,
+				    unsigned int allowed_mae_switch_port_types,
 				    efx_mport_sel_t *mport_sel);
 
 int sfc_mae_switch_get_entity_mport(uint16_t switch_domain_id,