Implement support for common flow parsing infrastructure in preparation for migration of flow engines.
Signed-off-by: Anatoly Burakov <[email protected]> --- drivers/net/intel/i40e/i40e_ethdev.c | 12 +++++++ drivers/net/intel/i40e/i40e_ethdev.h | 5 +++ drivers/net/intel/i40e/i40e_flow.c | 53 +++++++++++++++++++++++++++- drivers/net/intel/i40e/i40e_flow.h | 12 +++++++ 4 files changed, 81 insertions(+), 1 deletion(-) create mode 100644 drivers/net/intel/i40e/i40e_flow.h diff --git a/drivers/net/intel/i40e/i40e_ethdev.c b/drivers/net/intel/i40e/i40e_ethdev.c index b6b2d291ee..a9f6a5680b 100644 --- a/drivers/net/intel/i40e/i40e_ethdev.c +++ b/drivers/net/intel/i40e/i40e_ethdev.c @@ -42,6 +42,9 @@ #include "i40e_regs.h" #include "rte_pmd_i40e.h" #include "i40e_hash.h" +#include "i40e_flow.h" + +#include "../common/flow_engine.h" #define ETH_I40E_FLOATING_VEB_ARG "enable_floating_veb" #define ETH_I40E_FLOATING_VEB_LIST_ARG "floating_veb_list" @@ -1844,6 +1847,10 @@ eth_i40e_dev_init(struct rte_eth_dev *dev, void *init_params __rte_unused) /* reset all stats of the device, including pf and main vsi */ i40e_dev_stats_reset(dev); + /* initialize flow engine configuration */ + ci_flow_engine_conf_init(&pf->flow_engine_conf, + &i40e_flow_engine_list, dev->data); + return 0; err_init_fdir_filter_list: @@ -2700,6 +2707,9 @@ i40e_dev_close(struct rte_eth_dev *dev) if (rte_eal_process_type() != RTE_PROC_PRIMARY) return 0; + /* uninstall all flows while the HW is still alive */ + ci_flow_flush(&pf->flow_engine_conf, NULL); + ret = rte_eth_switch_domain_free(pf->switch_domain_id); if (ret) PMD_INIT_LOG(WARNING, "failed to free switch domain: %d", ret); @@ -2785,6 +2795,8 @@ i40e_dev_close(struct rte_eth_dev *dev) rte_free(p_flow); } + ci_flow_engine_conf_reset(&pf->flow_engine_conf); + /* release the fdir static allocated memory */ i40e_fdir_memory_cleanup(pf); diff --git a/drivers/net/intel/i40e/i40e_ethdev.h b/drivers/net/intel/i40e/i40e_ethdev.h index 1e64a2d280..16b67268f7 100644 --- a/drivers/net/intel/i40e/i40e_ethdev.h +++ b/drivers/net/intel/i40e/i40e_ethdev.h @@ -21,6 +21,8 @@ #include "base/i40e_type.h" #include "base/virtchnl.h" +#include "../common/flow_engine.h" + #define I40E_AQ_LEN 32 #define I40E_AQ_BUF_SZ 4096 /* Number of queues per TC should be one of 1, 2, 4, 8, 16, 32, 64 */ @@ -278,6 +280,7 @@ enum i40e_flxpld_layer_idx { * Struct to store flow created. */ struct rte_flow { + struct ci_flow base; TAILQ_ENTRY(rte_flow) node; enum rte_filter_type filter_type; void *rule; @@ -1182,6 +1185,8 @@ struct i40e_pf { /* The floating enable flag for the specific VF */ bool floating_veb_list[I40E_MAX_VF]; struct i40e_flow_list flow_list; + /* flow engine configuration */ + struct ci_flow_engine_conf flow_engine_conf; bool mpls_replace_flag; /* 1 - MPLS filter replace is done */ bool gtp_replace_flag; /* 1 - GTP-C/U filter replace is done */ bool qinq_replace_flag; /* QINQ filter replace is done */ diff --git a/drivers/net/intel/i40e/i40e_flow.c b/drivers/net/intel/i40e/i40e_flow.c index f0eea61b1e..b8b4e56414 100644 --- a/drivers/net/intel/i40e/i40e_flow.c +++ b/drivers/net/intel/i40e/i40e_flow.c @@ -26,9 +26,12 @@ #include "base/i40e_prototype.h" #include "i40e_ethdev.h" #include "i40e_hash.h" +#include "i40e_flow.h" #include "../common/flow_check.h" +const struct ci_flow_engine_list i40e_flow_engine_list = {0}; + #define I40E_IPV6_TC_MASK (0xFF << I40E_FDIR_IPv6_TC_OFFSET) #define I40E_IPV6_FRAG_HEADER 44 #define I40E_TENANT_ARRAY_NUM 3 @@ -1268,6 +1271,25 @@ i40e_flow_dev_dump(struct rte_eth_dev *dev, struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private); struct rte_flow *p_flow; bool found = false; + int ret; + + /* try the new flow engine first */ + ret = ci_flow_dump(&pf->flow_engine_conf, flow, file, error); + + /* + * There are multiple possible situations here: + * + * - User requested to dump all flows + * - User requested to dump a specific flow + * + * For the first case, we keep going because legacy engines might still + * have flows we want to dump. + * + * For the second case, we only keep going if the flow we were asked to + * dump was not found in the new engines. + */ + if (flow != NULL && ret == 0) + return 0; TAILQ_FOREACH(p_flow, &pf->flow_list, node) { size_t rule_size = 0; @@ -3892,8 +3914,15 @@ i40e_flow_validate(struct rte_eth_dev *dev, const struct rte_flow_action actions[], struct rte_flow_error *error) { + struct i40e_pf *pf = dev->data->dev_private; /* creates dummy context */ struct i40e_filter_ctx filter_ctx = {0}; + int ret; + + /* try the new engine first */ + ret = ci_flow_validate(&pf->flow_engine_conf, attr, pattern, actions, error); + if (ret == 0) + return 0; return i40e_flow_check(dev, attr, pattern, actions, &filter_ctx, error); } @@ -3911,6 +3940,11 @@ i40e_flow_create(struct rte_eth_dev *dev, struct i40e_fdir_info *fdir_info = &pf->fdir; int ret; + /* try the new engine first */ + flow = ci_flow_create(&pf->flow_engine_conf, attr, pattern, actions, error); + if (flow != NULL) + return flow; + ret = i40e_flow_check(dev, attr, pattern, actions, &filter_ctx, error); if (ret < 0) return NULL; @@ -4017,6 +4051,11 @@ i40e_flow_destroy(struct rte_eth_dev *dev, struct i40e_fdir_info *fdir_info = &pf->fdir; int ret = 0; + /* try the new engine first */ + ret = ci_flow_destroy(&pf->flow_engine_conf, flow, error); + if (ret == 0) + return 0; + switch (filter_type) { case RTE_ETH_FILTER_ETHERTYPE: ret = i40e_flow_destroy_ethertype_filter(pf, @@ -4161,6 +4200,11 @@ i40e_flow_flush(struct rte_eth_dev *dev, struct rte_flow_error *error) struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private); int ret; + /* flush the new engine first */ + ret = ci_flow_flush(&pf->flow_engine_conf, error); + if (ret != 0) + return ret; + ret = i40e_flow_flush_fdir_filter(pf); if (ret) { rte_flow_error_set(error, -ret, @@ -4310,14 +4354,21 @@ i40e_flow_flush_tunnel_filter(struct i40e_pf *pf) } static int -i40e_flow_query(struct rte_eth_dev *dev __rte_unused, +i40e_flow_query(struct rte_eth_dev *dev, struct rte_flow *flow, const struct rte_flow_action *actions, void *data, struct rte_flow_error *error) { + struct i40e_pf *pf = dev->data->dev_private; struct i40e_rss_filter *rss_rule = (struct i40e_rss_filter *)flow->rule; enum rte_filter_type filter_type = flow->filter_type; struct rte_flow_action_rss *rss_conf = data; + int ret; + + /* try the new engine first */ + ret = ci_flow_query(&pf->flow_engine_conf, flow, actions, data, error); + if (ret == 0) + return 0; if (!rss_rule) { rte_flow_error_set(error, EINVAL, diff --git a/drivers/net/intel/i40e/i40e_flow.h b/drivers/net/intel/i40e/i40e_flow.h new file mode 100644 index 0000000000..c958868661 --- /dev/null +++ b/drivers/net/intel/i40e/i40e_flow.h @@ -0,0 +1,12 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2026 Intel Corporation + */ + +#ifndef _I40E_FLOW_H_ +#define _I40E_FLOW_H_ + +#include "../common/flow_engine.h" + +extern const struct ci_flow_engine_list i40e_flow_engine_list; + +#endif /* _I40E_FLOW_H_ */ -- 2.52.0

