[PATCH v2 24/25] net/ice: use common action checks for switch
Anatoly Burakov
anatoly.burakov at intel.com
Mon Mar 16 11:52:49 CET 2026
From: Vladimir Medvedkin <vladimir.medvedkin at intel.com>
Use the common flow action checking parsing infrastructure for checking
flow actions for switch filter.
Signed-off-by: Vladimir Medvedkin <vladimir.medvedkin at intel.com>
---
drivers/net/intel/ice/ice_switch_filter.c | 370 +++++++++++-----------
1 file changed, 184 insertions(+), 186 deletions(-)
diff --git a/drivers/net/intel/ice/ice_switch_filter.c b/drivers/net/intel/ice/ice_switch_filter.c
index d8c0e7c59c..9a46e3b413 100644
--- a/drivers/net/intel/ice/ice_switch_filter.c
+++ b/drivers/net/intel/ice/ice_switch_filter.c
@@ -35,6 +35,8 @@
#define ICE_IPV4_PROTO_NVGRE 0x002F
#define ICE_SW_PRI_BASE 6
+#define ICE_SW_MAX_QUEUES 128
+
#define ICE_SW_INSET_ETHER ( \
ICE_INSET_DMAC | ICE_INSET_SMAC | ICE_INSET_ETHERTYPE)
#define ICE_SW_INSET_MAC_VLAN ( \
@@ -1527,85 +1529,38 @@ ice_switch_parse_pattern(const struct rte_flow_item pattern[],
}
static int
-ice_switch_parse_dcf_action(struct ice_dcf_adapter *ad,
- const struct rte_flow_action *actions,
+ice_switch_parse_dcf_action(const struct rte_flow_action *action,
uint32_t priority,
struct rte_flow_error *error,
struct ice_adv_rule_info *rule_info)
{
const struct rte_flow_action_ethdev *act_ethdev;
- const struct rte_flow_action *action;
const struct rte_eth_dev *repr_dev;
enum rte_flow_action_type action_type;
- uint16_t rule_port_id, backer_port_id;
- for (action = actions; action->type !=
- RTE_FLOW_ACTION_TYPE_END; action++) {
- action_type = action->type;
- switch (action_type) {
- case RTE_FLOW_ACTION_TYPE_PORT_REPRESENTOR:
- rule_info->sw_act.fltr_act = ICE_FWD_TO_VSI;
- act_ethdev = action->conf;
-
- if (!rte_eth_dev_is_valid_port(act_ethdev->port_id))
- goto invalid_port_id;
-
- /* For traffic to original DCF port */
- rule_port_id = ad->parent.pf.dev_data->port_id;
-
- if (rule_port_id != act_ethdev->port_id)
- goto invalid_port_id;
-
- rule_info->sw_act.vsi_handle = 0;
-
- break;
-
-invalid_port_id:
- rte_flow_error_set(error,
- EINVAL, RTE_FLOW_ERROR_TYPE_ACTION,
- actions,
- "Invalid port_id");
- return -rte_errno;
-
- case RTE_FLOW_ACTION_TYPE_REPRESENTED_PORT:
- rule_info->sw_act.fltr_act = ICE_FWD_TO_VSI;
- act_ethdev = action->conf;
-
- if (!rte_eth_dev_is_valid_port(act_ethdev->port_id))
- goto invalid;
-
- repr_dev = &rte_eth_devices[act_ethdev->port_id];
-
- if (!repr_dev->data)
- goto invalid;
-
- rule_port_id = ad->parent.pf.dev_data->port_id;
- backer_port_id = repr_dev->data->backer_port_id;
-
- if (backer_port_id != rule_port_id)
- goto invalid;
-
- rule_info->sw_act.vsi_handle = repr_dev->data->representor_id;
- break;
-
-invalid:
- rte_flow_error_set(error,
- EINVAL, RTE_FLOW_ERROR_TYPE_ACTION,
- actions,
- "Invalid ethdev_port_id");
- return -rte_errno;
-
- case RTE_FLOW_ACTION_TYPE_DROP:
- rule_info->sw_act.fltr_act = ICE_DROP_PACKET;
- break;
-
- default:
- rte_flow_error_set(error,
- EINVAL, RTE_FLOW_ERROR_TYPE_ACTION,
- actions,
- "Invalid action type");
- return -rte_errno;
- }
+ action_type = action->type;
+ switch (action_type) {
+ case RTE_FLOW_ACTION_TYPE_PORT_REPRESENTOR:
+ rule_info->sw_act.fltr_act = ICE_FWD_TO_VSI;
+ rule_info->sw_act.vsi_handle = 0;
+ break;
+
+ case RTE_FLOW_ACTION_TYPE_REPRESENTED_PORT:
+ rule_info->sw_act.fltr_act = ICE_FWD_TO_VSI;
+ act_ethdev = action->conf;
+ repr_dev = &rte_eth_devices[act_ethdev->port_id];
+ rule_info->sw_act.vsi_handle = repr_dev->data->representor_id;
+ break;
+
+ case RTE_FLOW_ACTION_TYPE_DROP:
+ rule_info->sw_act.fltr_act = ICE_DROP_PACKET;
+ break;
+
+ default:
+ /* Should never reach */
+ rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ACTION,
+ action, "Invalid action type");
+ return -rte_errno;
}
rule_info->sw_act.src = rule_info->sw_act.vsi_handle;
@@ -1621,73 +1576,38 @@ ice_switch_parse_dcf_action(struct ice_dcf_adapter *ad,
static int
ice_switch_parse_action(struct ice_pf *pf,
- const struct rte_flow_action *actions,
+ const struct rte_flow_action *action,
uint32_t priority,
struct rte_flow_error *error,
struct ice_adv_rule_info *rule_info)
{
struct ice_vsi *vsi = pf->main_vsi;
- struct rte_eth_dev_data *dev_data = pf->adapter->pf.dev_data;
const struct rte_flow_action_queue *act_q;
const struct rte_flow_action_rss *act_qgrop;
- uint16_t base_queue, i;
- const struct rte_flow_action *action;
+ uint16_t base_queue;
enum rte_flow_action_type action_type;
- uint16_t valid_qgrop_number[MAX_QGRP_NUM_TYPE] = {
- 2, 4, 8, 16, 32, 64, 128};
base_queue = pf->base_queue + vsi->base_queue;
- for (action = actions; action->type !=
- RTE_FLOW_ACTION_TYPE_END; action++) {
- action_type = action->type;
- switch (action_type) {
- case RTE_FLOW_ACTION_TYPE_RSS:
- act_qgrop = action->conf;
- if (act_qgrop->queue_num <= 1)
- goto error;
- rule_info->sw_act.fltr_act =
- ICE_FWD_TO_QGRP;
- rule_info->sw_act.fwd_id.q_id =
- base_queue + act_qgrop->queue[0];
- for (i = 0; i < MAX_QGRP_NUM_TYPE; i++) {
- if (act_qgrop->queue_num ==
- valid_qgrop_number[i])
- break;
- }
- if (i == MAX_QGRP_NUM_TYPE)
- goto error;
- if ((act_qgrop->queue[0] +
- act_qgrop->queue_num) >
- dev_data->nb_rx_queues)
- goto error1;
- for (i = 0; i < act_qgrop->queue_num - 1; i++)
- if (act_qgrop->queue[i + 1] !=
- act_qgrop->queue[i] + 1)
- goto error2;
- rule_info->sw_act.qgrp_size =
- act_qgrop->queue_num;
- break;
- case RTE_FLOW_ACTION_TYPE_QUEUE:
- act_q = action->conf;
- if (act_q->index >= dev_data->nb_rx_queues)
- goto error;
- rule_info->sw_act.fltr_act =
- ICE_FWD_TO_Q;
- rule_info->sw_act.fwd_id.q_id =
- base_queue + act_q->index;
- break;
-
- case RTE_FLOW_ACTION_TYPE_DROP:
- rule_info->sw_act.fltr_act =
- ICE_DROP_PACKET;
- break;
-
- case RTE_FLOW_ACTION_TYPE_VOID:
- break;
-
- default:
- goto error;
- }
+ action_type = action->type;
+ switch (action_type) {
+ case RTE_FLOW_ACTION_TYPE_RSS:
+ act_qgrop = action->conf;
+ rule_info->sw_act.fltr_act = ICE_FWD_TO_QGRP;
+ rule_info->sw_act.fwd_id.q_id = base_queue + act_qgrop->queue[0];
+ rule_info->sw_act.qgrp_size = act_qgrop->queue_num;
+ break;
+ case RTE_FLOW_ACTION_TYPE_QUEUE:
+ act_q = action->conf;
+ rule_info->sw_act.fltr_act = ICE_FWD_TO_Q;
+ rule_info->sw_act.fwd_id.q_id = base_queue + act_q->index;
+ break;
+ case RTE_FLOW_ACTION_TYPE_DROP:
+ rule_info->sw_act.fltr_act = ICE_DROP_PACKET;
+ break;
+ default:
+ rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ACTION,
+ action, "Invalid action type or queue number");
+ return -rte_errno;
}
rule_info->sw_act.vsi_handle = vsi->idx;
@@ -1699,65 +1619,120 @@ ice_switch_parse_action(struct ice_pf *pf,
rule_info->priority = ICE_SW_PRI_BASE - priority;
return 0;
-
-error:
- rte_flow_error_set(error,
- EINVAL, RTE_FLOW_ERROR_TYPE_ACTION,
- actions,
- "Invalid action type or queue number");
- return -rte_errno;
-
-error1:
- rte_flow_error_set(error,
- EINVAL, RTE_FLOW_ERROR_TYPE_ACTION,
- actions,
- "Invalid queue region indexes");
- return -rte_errno;
-
-error2:
- rte_flow_error_set(error,
- EINVAL, RTE_FLOW_ERROR_TYPE_ACTION,
- actions,
- "Discontinuous queue region");
- return -rte_errno;
}
static int
-ice_switch_check_action(const struct rte_flow_action *actions,
- struct rte_flow_error *error)
+ice_switch_dcf_action_check(const struct ci_flow_actions *actions,
+ const struct ci_flow_actions_check_param *param,
+ struct rte_flow_error *error)
{
+ struct ice_dcf_adapter *ad = param->driver_ctx;
const struct rte_flow_action *action;
enum rte_flow_action_type action_type;
- uint16_t actions_num = 0;
-
- for (action = actions; action->type !=
- RTE_FLOW_ACTION_TYPE_END; action++) {
- action_type = action->type;
- switch (action_type) {
- case RTE_FLOW_ACTION_TYPE_RSS:
- case RTE_FLOW_ACTION_TYPE_QUEUE:
- case RTE_FLOW_ACTION_TYPE_DROP:
- case RTE_FLOW_ACTION_TYPE_REPRESENTED_PORT:
- case RTE_FLOW_ACTION_TYPE_PORT_REPRESENTOR:
- actions_num++;
- break;
- case RTE_FLOW_ACTION_TYPE_VOID:
- continue;
- default:
- rte_flow_error_set(error,
- EINVAL, RTE_FLOW_ERROR_TYPE_ACTION,
- actions,
- "Invalid action type");
- return -rte_errno;
+ const struct rte_flow_action_ethdev *act_ethdev;
+ const struct rte_eth_dev *repr_dev;
+
+ action = actions->actions[0];
+ action_type = action->type;
+
+ switch (action_type) {
+ case RTE_FLOW_ACTION_TYPE_PORT_REPRESENTOR:
+ case RTE_FLOW_ACTION_TYPE_REPRESENTED_PORT:
+ {
+ uint16_t expected_port_id, backer_port_id;
+ act_ethdev = action->conf;
+
+ if (!rte_eth_dev_is_valid_port(act_ethdev->port_id))
+ goto invalid_port_id;
+
+ expected_port_id = ad->parent.pf.dev_data->port_id;
+
+ if (action_type == RTE_FLOW_ACTION_TYPE_PORT_REPRESENTOR) {
+ if (expected_port_id != act_ethdev->port_id)
+ goto invalid_port_id;
+ } else {
+ repr_dev = &rte_eth_devices[act_ethdev->port_id];
+
+ if (!repr_dev->data)
+ goto invalid_port_id;
+
+ backer_port_id = repr_dev->data->backer_port_id;
+
+ if (backer_port_id != expected_port_id)
+ goto invalid_port_id;
}
+
+ break;
+invalid_port_id:
+ return rte_flow_error_set(error, EINVAL,
+ RTE_FLOW_ERROR_TYPE_ACTION, action,
+ "Invalid port ID");
+ }
+ case RTE_FLOW_ACTION_TYPE_DROP:
+ break;
+ default:
+ /* Should never reach */
+ return rte_flow_error_set(error, EINVAL,
+ RTE_FLOW_ERROR_TYPE_ACTION, action,
+ "Invalid action type");
}
- if (actions_num != 1) {
- rte_flow_error_set(error,
- EINVAL, RTE_FLOW_ERROR_TYPE_ACTION,
- actions,
- "Invalid action number");
- return -rte_errno;
+ return 0;
+}
+
+static int
+ice_switch_action_check(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;
+ struct rte_eth_dev_data *dev_data = pf->dev_data;
+ const struct rte_flow_action *action = actions->actions[0];
+
+ switch (action->type) {
+ case RTE_FLOW_ACTION_TYPE_RSS:
+ {
+ const struct rte_flow_action_rss *act_qgrop;
+ act_qgrop = action->conf;
+
+ /* Check bounds on number of queues */
+ if (act_qgrop->queue_num < 2 || act_qgrop->queue_num > ICE_SW_MAX_QUEUES)
+ goto err_rss;
+
+ /* must be power of 2 */
+ if (!rte_is_power_of_2(act_qgrop->queue_num))
+ goto err_rss;
+
+ /* queues are monotonous and contiguous so check last queue */
+ if ((act_qgrop->queue[0] + act_qgrop->queue_num) > dev_data->nb_rx_queues)
+ goto err_rss;
+
+ break;
+err_rss:
+ return rte_flow_error_set(error, EINVAL,
+ RTE_FLOW_ERROR_TYPE_ACTION, action,
+ "Invalid queue region");
+ }
+ case RTE_FLOW_ACTION_TYPE_QUEUE:
+ {
+ const struct rte_flow_action_queue *act_q;
+ act_q = action->conf;
+ if (act_q->index >= dev_data->nb_rx_queues) {
+ return rte_flow_error_set(error, EINVAL,
+ RTE_FLOW_ERROR_TYPE_ACTION, action,
+ "Invalid queue");
+ }
+
+ break;
+ }
+ case RTE_FLOW_ACTION_TYPE_DROP:
+ break;
+ default:
+ /* Should never reach */
+ return rte_flow_error_set(error, EINVAL,
+ RTE_FLOW_ERROR_TYPE_ACTION, action,
+ "Invalid action type");
}
return 0;
@@ -1788,11 +1763,38 @@ ice_switch_parse_pattern_action(struct ice_adapter *ad,
struct ci_flow_attr_check_param attr_param = {
.allow_priority = true,
};
+ struct ci_flow_actions parsed_actions = {0};
+ struct ci_flow_actions_check_param dcf_param = {
+ .allowed_types = (enum rte_flow_action_type[]){
+ RTE_FLOW_ACTION_TYPE_REPRESENTED_PORT,
+ RTE_FLOW_ACTION_TYPE_PORT_REPRESENTOR,
+ RTE_FLOW_ACTION_TYPE_DROP,
+ RTE_FLOW_ACTION_TYPE_END
+ },
+ .max_actions = 1,
+ .check = ice_switch_dcf_action_check,
+ };
+ struct ci_flow_actions_check_param param = {
+ .allowed_types = (enum rte_flow_action_type[]){
+ RTE_FLOW_ACTION_TYPE_RSS,
+ RTE_FLOW_ACTION_TYPE_QUEUE,
+ RTE_FLOW_ACTION_TYPE_DROP,
+ RTE_FLOW_ACTION_TYPE_END
+ },
+ .max_actions = 1,
+ .check = ice_switch_action_check,
+ .driver_ctx = ad,
+ };
ret = ci_flow_check_attr(attr, &attr_param, error);
if (ret)
return ret;
+ ret = ci_flow_check_actions(actions, (ad->hw.dcf_enabled) ? &dcf_param : ¶m,
+ &parsed_actions, error);
+ if (ret)
+ goto error;
+
/* Allow only two priority values - 0 or 1 */
if (attr->priority > 1) {
rte_flow_error_set(error, EINVAL,
@@ -1870,16 +1872,12 @@ ice_switch_parse_pattern_action(struct ice_adapter *ad,
memset(&rule_info, 0, sizeof(rule_info));
rule_info.tun_type = tun_type;
- ret = ice_switch_check_action(actions, error);
- if (ret)
- goto error;
-
if (ad->hw.dcf_enabled)
- ret = ice_switch_parse_dcf_action((void *)ad, actions, attr->priority,
- error, &rule_info);
+ ret = ice_switch_parse_dcf_action(parsed_actions.actions[0],
+ attr->priority, error, &rule_info);
else
- ret = ice_switch_parse_action(pf, actions, attr->priority, error,
- &rule_info);
+ ret = ice_switch_parse_action(pf, parsed_actions.actions[0],
+ attr->priority, error, &rule_info);
if (ret)
goto error;
--
2.47.3
More information about the dev
mailing list