[v2,3/4] net/nfp: add call to add and delete the flows to firmware

Message ID 20231004093602.1278126-4-chaoyong.he@corigine.com (mailing list archive)
State Accepted, archived
Delegated to: Ferruh Yigit
Headers
Series support offload of simple conntrack flow rules |

Checks

Context Check Description
ci/checkpatch success coding style OK

Commit Message

Chaoyong He Oct. 4, 2023, 9:36 a.m. UTC
  Add the offload call to add and delete the flows to the firmware.

Signed-off-by: Chaoyong He <chaoyong.he@corigine.com>
---
 drivers/net/nfp/flower/nfp_conntrack.c | 112 ++++++++++++++++++++++++-
 drivers/net/nfp/flower/nfp_conntrack.h |   5 ++
 drivers/net/nfp/nfp_flow.c             |   8 ++
 3 files changed, 122 insertions(+), 3 deletions(-)
  

Patch

diff --git a/drivers/net/nfp/flower/nfp_conntrack.c b/drivers/net/nfp/flower/nfp_conntrack.c
index 4fa6fdff99..2ea856ebab 100644
--- a/drivers/net/nfp/flower/nfp_conntrack.c
+++ b/drivers/net/nfp/flower/nfp_conntrack.c
@@ -9,8 +9,8 @@ 
 #include <rte_hash.h>
 #include <rte_jhash.h>
 
-#include "../nfp_flow.h"
 #include "../nfp_logs.h"
+#include "nfp_flower_cmsg.h"
 #include "nfp_flower_representor.h"
 
 struct ct_data {
@@ -59,6 +59,7 @@  struct nfp_ct_merge_entry {
 	LIST_ENTRY(nfp_ct_merge_entry) pre_ct_list;
 	LIST_ENTRY(nfp_ct_merge_entry) post_ct_list;
 	struct nfp_initial_flow rule;
+	struct rte_flow *compiled_rule;
 	struct nfp_ct_zone_entry *ze;
 	struct nfp_ct_flow_entry *pre_ct_parent;
 	struct nfp_ct_flow_entry *post_ct_parent;
@@ -974,6 +975,102 @@  nfp_ct_zone_entry_free(struct nfp_ct_zone_entry *ze,
 	}
 }
 
+static int
+nfp_ct_offload_add(struct nfp_flower_representor *repr,
+		struct nfp_ct_merge_entry *merge_entry)
+{
+	int ret;
+	uint64_t cookie;
+	struct rte_flow *nfp_flow;
+	struct nfp_flow_priv *priv;
+	const struct rte_flow_item *items;
+	const struct rte_flow_action *actions;
+
+	cookie = rte_rand();
+	items = merge_entry->rule.items;
+	actions = merge_entry->rule.actions;
+	nfp_flow = nfp_flow_process(repr, items, actions, false, cookie, true);
+	if (nfp_flow == NULL) {
+		PMD_DRV_LOG(ERR, "Process the merged flow rule failed.");
+		return -EINVAL;
+	}
+
+	/* Add the flow to hardware */
+	priv = repr->app_fw_flower->flow_priv;
+	ret = nfp_flower_cmsg_flow_add(repr->app_fw_flower, nfp_flow);
+	if (ret != 0) {
+		PMD_DRV_LOG(ERR, "Add the merged flow to firmware failed.");
+		goto flow_teardown;
+	}
+
+	/* Add the flow to flow hash table */
+	ret = nfp_flow_table_add(priv, nfp_flow);
+	if (ret != 0) {
+		PMD_DRV_LOG(ERR, "Add the merged flow to flow table failed.");
+		goto flow_teardown;
+	}
+
+	merge_entry->compiled_rule = nfp_flow;
+
+	return 0;
+
+flow_teardown:
+	nfp_flow_teardown(priv, nfp_flow, false);
+	nfp_flow_free(nfp_flow);
+
+	return ret;
+}
+
+int
+nfp_ct_offload_del(struct rte_eth_dev *dev,
+		struct nfp_ct_map_entry *me,
+		struct rte_flow_error *error)
+{
+	int ret;
+	struct nfp_ct_flow_entry *fe;
+	struct nfp_ct_merge_entry *m_ent;
+
+	fe = me->fe;
+
+	if (fe->type == CT_TYPE_PRE_CT) {
+		LIST_FOREACH(m_ent, &fe->children, pre_ct_list) {
+			if (m_ent->compiled_rule != NULL) {
+				ret = nfp_flow_destroy(dev, m_ent->compiled_rule, error);
+				if (ret != 0) {
+					PMD_DRV_LOG(ERR, "Could not alloc ct_flow_item");
+					return -EINVAL;
+				}
+				m_ent->compiled_rule = NULL;
+			}
+
+			m_ent->pre_ct_parent = NULL;
+			LIST_REMOVE(m_ent, pre_ct_list);
+			if (m_ent->post_ct_parent == NULL)
+				nfp_ct_merge_entry_destroy(m_ent);
+		}
+	} else {
+		LIST_FOREACH(m_ent, &fe->children, post_ct_list) {
+			if (m_ent->compiled_rule != NULL) {
+				ret = nfp_flow_destroy(dev, m_ent->compiled_rule, error);
+				if (ret != 0) {
+					PMD_DRV_LOG(ERR, "Could not alloc ct_flow_item");
+					return -EINVAL;
+				}
+				m_ent->compiled_rule = NULL;
+			}
+
+			m_ent->post_ct_parent = NULL;
+			LIST_REMOVE(m_ent, post_ct_list);
+			if (m_ent->pre_ct_parent == NULL)
+				nfp_ct_merge_entry_destroy(m_ent);
+		}
+	}
+
+	nfp_ct_flow_entry_destroy_partly(fe);
+
+	return 0;
+}
+
 static inline bool
 is_item_check_pass(const struct rte_flow_item *item1,
 		const struct rte_flow_item *item2,
@@ -1401,8 +1498,17 @@  nfp_ct_do_flow_merge(struct nfp_ct_zone_entry *ze,
 		goto free_actions;
 	}
 
+	/* Send to firmware */
+	ret = nfp_ct_offload_add(pre_ct_entry->repr, merge_entry);
+	if (ret != 0) {
+		PMD_DRV_LOG(ERR, "Send the merged flow to firmware failed");
+		goto merge_table_del;
+	}
+
 	return true;
 
+merge_table_del:
+	nfp_ct_merge_table_delete(ze, merge_entry);
 free_actions:
 	rte_free(merge_entry->rule.actions);
 free_items:
@@ -1489,7 +1595,7 @@  nfp_flow_handle_pre_ct(const struct rte_flow_item *ct_item,
 		}
 	}
 
-	/* The real offload logic comes in next commit, so here just return false for now */
+	return true;
 
 ct_flow_entry_free:
 	nfp_ct_flow_entry_destroy(fe);
@@ -1558,7 +1664,7 @@  nfp_flow_handle_post_ct(const struct rte_flow_item *ct_item,
 	if (!ret)
 		goto ct_flow_entry_free;
 
-	/* The real offload logic comes in next commit, so here just return false for now */
+	return true;
 
 ct_flow_entry_free:
 	nfp_ct_flow_entry_destroy(fe);
diff --git a/drivers/net/nfp/flower/nfp_conntrack.h b/drivers/net/nfp/flower/nfp_conntrack.h
index 149a3eb040..2f47280716 100644
--- a/drivers/net/nfp/flower/nfp_conntrack.h
+++ b/drivers/net/nfp/flower/nfp_conntrack.h
@@ -8,6 +8,7 @@ 
 
 #include <stdbool.h>
 
+#include <ethdev_driver.h>
 #include <rte_flow.h>
 
 #include "../nfp_flow.h"
@@ -22,6 +23,10 @@  struct nfp_ct_map_entry *nfp_ct_map_table_search(struct nfp_flow_priv *priv,
 		char *hash_data,
 		uint32_t hash_len);
 
+int nfp_ct_offload_del(struct rte_eth_dev *dev,
+		struct nfp_ct_map_entry *me,
+		struct rte_flow_error *error);
+
 struct rte_flow *nfp_ct_flow_setup(struct nfp_flower_representor *representor,
 		const struct rte_flow_item items[],
 		const struct rte_flow_action actions[],
diff --git a/drivers/net/nfp/nfp_flow.c b/drivers/net/nfp/nfp_flow.c
index 16a5c7e055..a6439679d3 100644
--- a/drivers/net/nfp/nfp_flow.c
+++ b/drivers/net/nfp/nfp_flow.c
@@ -3911,8 +3911,10 @@  nfp_flow_destroy(struct rte_eth_dev *dev,
 		struct rte_flow_error *error)
 {
 	int ret;
+	uint64_t cookie;
 	struct rte_flow *flow_find;
 	struct nfp_flow_priv *priv;
+	struct nfp_ct_map_entry *me;
 	struct nfp_app_fw_flower *app_fw_flower;
 	struct nfp_flower_representor *representor;
 
@@ -3920,6 +3922,12 @@  nfp_flow_destroy(struct rte_eth_dev *dev,
 	app_fw_flower = representor->app_fw_flower;
 	priv = app_fw_flower->flow_priv;
 
+	/* Find the flow in ct_map_table */
+	cookie = rte_be_to_cpu_64(nfp_flow->payload.meta->host_cookie);
+	me = nfp_ct_map_table_search(priv, (char *)&cookie, sizeof(uint64_t));
+	if (me != NULL)
+		return nfp_ct_offload_del(dev, me, error);
+
 	/* Find the flow in flow hash table */
 	flow_find = nfp_flow_table_search(priv, nfp_flow);
 	if (flow_find == NULL) {