[PATCH v2 23/25] net/ice: use common action checks for FDIR
Anatoly Burakov
anatoly.burakov at intel.com
Mon Mar 16 11:52:48 CET 2026
From: Vladimir Medvedkin <vladimir.medvedkin at intel.com>
Use the common flow action checking parsing infrastructure for checking
flow actions for FDIR filter.
Signed-off-by: Vladimir Medvedkin <vladimir.medvedkin at intel.com>
---
drivers/net/intel/ice/ice_fdir_filter.c | 375 +++++++++++++-----------
1 file changed, 203 insertions(+), 172 deletions(-)
diff --git a/drivers/net/intel/ice/ice_fdir_filter.c b/drivers/net/intel/ice/ice_fdir_filter.c
index f5b832b863..21eb394932 100644
--- a/drivers/net/intel/ice/ice_fdir_filter.c
+++ b/drivers/net/intel/ice/ice_fdir_filter.c
@@ -1690,177 +1690,6 @@ static struct ice_flow_engine ice_fdir_engine = {
.type = ICE_FLOW_ENGINE_FDIR,
};
-static int
-ice_fdir_parse_action_qregion(struct ice_pf *pf,
- struct rte_flow_error *error,
- const struct rte_flow_action *act,
- struct ice_fdir_filter_conf *filter)
-{
- const struct rte_flow_action_rss *rss = act->conf;
- uint32_t i;
-
- if (act->type != RTE_FLOW_ACTION_TYPE_RSS) {
- rte_flow_error_set(error, EINVAL,
- RTE_FLOW_ERROR_TYPE_ACTION, act,
- "Invalid action.");
- return -rte_errno;
- }
-
- if (rss->queue_num <= 1) {
- rte_flow_error_set(error, EINVAL,
- RTE_FLOW_ERROR_TYPE_ACTION, act,
- "Queue region size can't be 0 or 1.");
- return -rte_errno;
- }
-
- /* check if queue index for queue region is continuous */
- for (i = 0; i < rss->queue_num - 1; i++) {
- if (rss->queue[i + 1] != rss->queue[i] + 1) {
- rte_flow_error_set(error, EINVAL,
- RTE_FLOW_ERROR_TYPE_ACTION, act,
- "Discontinuous queue region");
- return -rte_errno;
- }
- }
-
- if (rss->queue[rss->queue_num - 1] >= pf->dev_data->nb_rx_queues) {
- rte_flow_error_set(error, EINVAL,
- RTE_FLOW_ERROR_TYPE_ACTION, act,
- "Invalid queue region indexes.");
- return -rte_errno;
- }
-
- if (!(rte_is_power_of_2(rss->queue_num) &&
- (rss->queue_num <= ICE_FDIR_MAX_QREGION_SIZE))) {
- rte_flow_error_set(error, EINVAL,
- RTE_FLOW_ERROR_TYPE_ACTION, act,
- "The region size should be any of the following values:"
- "1, 2, 4, 8, 16, 32, 64, 128 as long as the total number "
- "of queues do not exceed the VSI allocation.");
- return -rte_errno;
- }
-
- filter->input.q_index = rss->queue[0];
- filter->input.q_region = rte_fls_u32(rss->queue_num) - 1;
- filter->input.dest_ctl = ICE_FLTR_PRGM_DESC_DEST_DIRECT_PKT_QGROUP;
-
- return 0;
-}
-
-static int
-ice_fdir_parse_action(struct ice_adapter *ad,
- const struct rte_flow_action actions[],
- struct rte_flow_error *error,
- struct ice_fdir_filter_conf *filter)
-{
- struct ice_pf *pf = &ad->pf;
- const struct rte_flow_action_queue *act_q;
- const struct rte_flow_action_mark *mark_spec = NULL;
- const struct rte_flow_action_count *act_count;
- uint32_t dest_num = 0;
- uint32_t mark_num = 0;
- uint32_t counter_num = 0;
- int ret;
-
- for (; actions->type != RTE_FLOW_ACTION_TYPE_END; actions++) {
- switch (actions->type) {
- case RTE_FLOW_ACTION_TYPE_VOID:
- break;
- case RTE_FLOW_ACTION_TYPE_QUEUE:
- dest_num++;
-
- act_q = actions->conf;
- filter->input.q_index = act_q->index;
- if (filter->input.q_index >=
- pf->dev_data->nb_rx_queues) {
- rte_flow_error_set(error, EINVAL,
- RTE_FLOW_ERROR_TYPE_ACTION,
- actions,
- "Invalid queue for FDIR.");
- return -rte_errno;
- }
- filter->input.dest_ctl =
- ICE_FLTR_PRGM_DESC_DEST_DIRECT_PKT_QINDEX;
- break;
- case RTE_FLOW_ACTION_TYPE_DROP:
- dest_num++;
-
- filter->input.dest_ctl =
- ICE_FLTR_PRGM_DESC_DEST_DROP_PKT;
- break;
- case RTE_FLOW_ACTION_TYPE_PASSTHRU:
- dest_num++;
-
- filter->input.dest_ctl =
- ICE_FLTR_PRGM_DESC_DEST_DIRECT_PKT_OTHER;
- break;
- case RTE_FLOW_ACTION_TYPE_RSS:
- dest_num++;
-
- ret = ice_fdir_parse_action_qregion(pf,
- error, actions, filter);
- if (ret)
- return ret;
- break;
- case RTE_FLOW_ACTION_TYPE_MARK:
- mark_num++;
- filter->mark_flag = 1;
- mark_spec = actions->conf;
- filter->input.fltr_id = mark_spec->id;
- filter->input.fdid_prio = ICE_FXD_FLTR_QW1_FDID_PRI_ONE;
- break;
- case RTE_FLOW_ACTION_TYPE_COUNT:
- counter_num++;
-
- act_count = actions->conf;
- filter->input.cnt_ena = ICE_FXD_FLTR_QW0_STAT_ENA_PKTS;
- rte_memcpy(&filter->act_count, act_count,
- sizeof(filter->act_count));
-
- break;
- default:
- rte_flow_error_set(error, EINVAL,
- RTE_FLOW_ERROR_TYPE_ACTION, actions,
- "Invalid action.");
- return -rte_errno;
- }
- }
-
- if (dest_num >= 2) {
- rte_flow_error_set(error, EINVAL,
- RTE_FLOW_ERROR_TYPE_ACTION, actions,
- "Unsupported action combination");
- return -rte_errno;
- }
-
- if (mark_num >= 2) {
- rte_flow_error_set(error, EINVAL,
- RTE_FLOW_ERROR_TYPE_ACTION, actions,
- "Too many mark actions");
- return -rte_errno;
- }
-
- if (counter_num >= 2) {
- rte_flow_error_set(error, EINVAL,
- RTE_FLOW_ERROR_TYPE_ACTION, actions,
- "Too many count actions");
- return -rte_errno;
- }
-
- if (dest_num + mark_num + counter_num == 0) {
- rte_flow_error_set(error, EINVAL,
- RTE_FLOW_ERROR_TYPE_ACTION, actions,
- "Empty action");
- return -rte_errno;
- }
-
- /* set default action to PASSTHRU mode, in "mark/count only" case. */
- if (dest_num == 0)
- filter->input.dest_ctl =
- ICE_FLTR_PRGM_DESC_DEST_DIRECT_PKT_OTHER;
-
- return 0;
-}
static int
ice_fdir_parse_pattern(__rte_unused struct ice_adapter *ad,
@@ -2792,6 +2621,188 @@ ice_fdir_parse_pattern(__rte_unused struct ice_adapter *ad,
return 0;
}
+static int
+ice_fdir_parse_action(struct ice_adapter *ad,
+ const struct ci_flow_actions *actions,
+ struct rte_flow_error *error)
+{
+ struct ice_pf *pf = &ad->pf;
+ struct ice_fdir_filter_conf *filter = &pf->fdir.conf;
+ bool dest_set = false;
+ size_t i;
+
+ for (i = 0; i < actions->count; i++) {
+ const struct rte_flow_action *act = actions->actions[i];
+
+ switch (act->type) {
+ case RTE_FLOW_ACTION_TYPE_QUEUE:
+ {
+ const struct rte_flow_action_queue *act_q = act->conf;
+ dest_set = true;
+
+ filter->input.q_index = act_q->index;
+ filter->input.dest_ctl =
+ ICE_FLTR_PRGM_DESC_DEST_DIRECT_PKT_QINDEX;
+ break;
+ }
+ case RTE_FLOW_ACTION_TYPE_DROP:
+ dest_set = true;
+
+ filter->input.dest_ctl =
+ ICE_FLTR_PRGM_DESC_DEST_DROP_PKT;
+ break;
+ case RTE_FLOW_ACTION_TYPE_PASSTHRU:
+ dest_set = true;
+
+ filter->input.dest_ctl =
+ ICE_FLTR_PRGM_DESC_DEST_DIRECT_PKT_OTHER;
+ break;
+ case RTE_FLOW_ACTION_TYPE_RSS:
+ {
+ const struct rte_flow_action_rss *rss = act->conf;
+ dest_set = true;
+
+ filter->input.q_index = rss->queue[0];
+ filter->input.q_region = rte_fls_u32(rss->queue_num) - 1;
+ filter->input.dest_ctl = ICE_FLTR_PRGM_DESC_DEST_DIRECT_PKT_QGROUP;
+
+ break;
+ }
+ case RTE_FLOW_ACTION_TYPE_MARK:
+ {
+ const struct rte_flow_action_mark *mark_spec = act->conf;
+ filter->mark_flag = 1;
+ filter->input.fltr_id = mark_spec->id;
+ filter->input.fdid_prio = ICE_FXD_FLTR_QW1_FDID_PRI_ONE;
+ break;
+ }
+ case RTE_FLOW_ACTION_TYPE_COUNT:
+ {
+ const struct rte_flow_action_count *act_count = act->conf;
+
+ filter->input.cnt_ena = ICE_FXD_FLTR_QW0_STAT_ENA_PKTS;
+ rte_memcpy(&filter->act_count, act_count,
+ sizeof(filter->act_count));
+ break;
+ }
+ default:
+ /* Should not happen */
+ return rte_flow_error_set(error, EINVAL,
+ RTE_FLOW_ERROR_TYPE_ACTION, act,
+ "Invalid action.");
+ }
+ }
+
+ /* set default action to PASSTHRU mode, in "mark/count only" case. */
+ if (!dest_set) {
+ filter->input.dest_ctl =
+ ICE_FLTR_PRGM_DESC_DEST_DIRECT_PKT_OTHER;
+ }
+
+ return 0;
+}
+
+static int
+ice_fdir_check_action_qregion(struct ice_pf *pf,
+ struct rte_flow_error *error,
+ const struct rte_flow_action_rss *rss)
+{
+ if (rss->queue_num <= 1) {
+ return rte_flow_error_set(error, EINVAL,
+ RTE_FLOW_ERROR_TYPE_ACTION_CONF, rss,
+ "Queue region size can't be 0 or 1.");
+ }
+
+ if (rss->queue[rss->queue_num - 1] >= pf->dev_data->nb_rx_queues) {
+ return rte_flow_error_set(error, EINVAL,
+ RTE_FLOW_ERROR_TYPE_ACTION_CONF, rss,
+ "Invalid queue region indexes.");
+ }
+
+ if (!(rte_is_power_of_2(rss->queue_num) &&
+ rss->queue_num <= ICE_FDIR_MAX_QREGION_SIZE))
+ return rte_flow_error_set(error, EINVAL,
+ RTE_FLOW_ERROR_TYPE_ACTION_CONF, rss,
+ "The region size should be any of the following values:"
+ "2, 4, 8, 16, 32, 64, 128 as long as the total number "
+ "of queues do not exceed the VSI allocation.");
+
+ return 0;
+}
+
+static int
+ice_fdir_check_action(const struct ci_flow_actions *actions,
+ const struct ci_flow_actions_check_param *param,
+ struct rte_flow_error *error)
+{
+ struct ice_adapter *ad = param->driver_ctx;
+ struct ice_pf *pf = &ad->pf;
+ uint32_t dest_num = 0;
+ uint32_t mark_num = 0;
+ uint32_t counter_num = 0;
+ size_t i;
+ int ret;
+
+ for (i = 0; i < actions->count; i++) {
+ const struct rte_flow_action *act = actions->actions[i];
+
+ switch (act->type) {
+ case RTE_FLOW_ACTION_TYPE_QUEUE:
+ {
+ const struct rte_flow_action_queue *act_q = act->conf;
+ dest_num++;
+
+ if (act_q->index >= pf->dev_data->nb_rx_queues) {
+ return rte_flow_error_set(error, EINVAL,
+ RTE_FLOW_ERROR_TYPE_ACTION,
+ act,
+ "Invalid queue for FDIR.");
+ }
+ break;
+ }
+ case RTE_FLOW_ACTION_TYPE_DROP:
+ dest_num++;
+ break;
+ case RTE_FLOW_ACTION_TYPE_PASSTHRU:
+ dest_num++;
+ break;
+ case RTE_FLOW_ACTION_TYPE_RSS:
+ {
+ const struct rte_flow_action_rss *rss = act->conf;
+
+ dest_num++;
+ ret = ice_fdir_check_action_qregion(pf, error, rss);
+ if (ret)
+ return ret;
+ break;
+ }
+ case RTE_FLOW_ACTION_TYPE_MARK:
+ {
+ mark_num++;
+ break;
+ }
+ case RTE_FLOW_ACTION_TYPE_COUNT:
+ {
+ counter_num++;
+ break;
+ }
+ default:
+ /* Should not happen */
+ return rte_flow_error_set(error, EINVAL,
+ RTE_FLOW_ERROR_TYPE_ACTION, act,
+ "Invalid action.");
+ }
+ }
+
+ if (dest_num > 1 || mark_num > 1 || counter_num > 1) {
+ return rte_flow_error_set(error, EINVAL,
+ RTE_FLOW_ERROR_TYPE_ACTION, NULL,
+ "Unsupported action combination");
+ }
+
+ return 0;
+}
+
static int
ice_fdir_parse(struct ice_adapter *ad,
struct ice_pattern_match_item *array,
@@ -2802,6 +2813,21 @@ ice_fdir_parse(struct ice_adapter *ad,
void **meta,
struct rte_flow_error *error)
{
+ struct ci_flow_actions parsed_actions = {0};
+ struct ci_flow_actions_check_param param = {
+ .allowed_types = (enum rte_flow_action_type[]){
+ RTE_FLOW_ACTION_TYPE_PASSTHRU,
+ RTE_FLOW_ACTION_TYPE_DROP,
+ RTE_FLOW_ACTION_TYPE_QUEUE,
+ RTE_FLOW_ACTION_TYPE_RSS,
+ RTE_FLOW_ACTION_TYPE_MARK,
+ RTE_FLOW_ACTION_TYPE_COUNT,
+ RTE_FLOW_ACTION_TYPE_END
+ },
+ .max_actions = 3,
+ .check = ice_fdir_check_action,
+ .driver_ctx = ad,
+ };
struct ice_pf *pf = &ad->pf;
struct ice_fdir_filter_conf *filter = &pf->fdir.conf;
struct ice_pattern_match_item *item = NULL;
@@ -2814,6 +2840,11 @@ ice_fdir_parse(struct ice_adapter *ad,
return ret;
memset(filter, 0, sizeof(*filter));
+
+ ret = ci_flow_check_actions(actions, ¶m, &parsed_actions, error);
+ if (ret)
+ return ret;
+
item = ice_search_pattern_match_item(ad, pattern, array, array_len,
error);
@@ -2842,7 +2873,7 @@ ice_fdir_parse(struct ice_adapter *ad,
goto error;
}
- ret = ice_fdir_parse_action(ad, actions, error, filter);
+ ret = ice_fdir_parse_action(ad, &parsed_actions, error);
if (ret)
goto error;
--
2.47.3
More information about the dev
mailing list