[PATCH v2 14/25] net/i40e: use common action checks for tunnel
Anatoly Burakov
anatoly.burakov at intel.com
Mon Mar 16 11:52:39 CET 2026
Use the common flow action checking parsing infrastructure for checking
flow actions for flow director tunnel filter. As a result, more stringent
checks are performed against parametersm specifically the following:
- reject NULL conf for VF action (instead of attempt at NULL dereference)
- second action was expected to be QUEUE but if it wasn't it was ignored
Signed-off-by: Anatoly Burakov <anatoly.burakov at intel.com>
---
drivers/net/intel/i40e/i40e_flow.c | 104 +++++++++++++----------------
1 file changed, 48 insertions(+), 56 deletions(-)
diff --git a/drivers/net/intel/i40e/i40e_flow.c b/drivers/net/intel/i40e/i40e_flow.c
index 3470f35a20..88cdc59429 100644
--- a/drivers/net/intel/i40e/i40e_flow.c
+++ b/drivers/net/intel/i40e/i40e_flow.c
@@ -1104,15 +1104,6 @@ static struct i40e_valid_pattern i40e_supported_patterns[] = {
{ pattern_fdir_ipv6_sctp, i40e_flow_parse_l4_cloud_filter },
};
-#define NEXT_ITEM_OF_ACTION(act, actions, index) \
- do { \
- act = actions + index; \
- while (act->type == RTE_FLOW_ACTION_TYPE_VOID) { \
- index++; \
- act = actions + index; \
- } \
- } while (0)
-
/* Find the first VOID or non-VOID item pointer */
static const struct rte_flow_item *
i40e_find_first_item(const struct rte_flow_item *item, bool is_void)
@@ -2539,61 +2530,62 @@ i40e_flow_parse_tunnel_action(struct rte_eth_dev *dev,
struct i40e_tunnel_filter_conf *filter)
{
struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
- const struct rte_flow_action *act;
const struct rte_flow_action_queue *act_q;
- const struct rte_flow_action_vf *act_vf;
- uint32_t index = 0;
+ struct ci_flow_actions parsed_actions = {0};
+ struct ci_flow_actions_check_param ac_param = {
+ .allowed_types = (enum rte_flow_action_type[]) {
+ RTE_FLOW_ACTION_TYPE_QUEUE,
+ RTE_FLOW_ACTION_TYPE_PF,
+ RTE_FLOW_ACTION_TYPE_VF,
+ RTE_FLOW_ACTION_TYPE_END
+ },
+ .max_actions = 2,
+ };
+ const struct rte_flow_action *first, *second;
+ int ret;
- /* Check if the first non-void action is PF or VF. */
- NEXT_ITEM_OF_ACTION(act, actions, index);
- if (act->type != RTE_FLOW_ACTION_TYPE_PF &&
- act->type != RTE_FLOW_ACTION_TYPE_VF) {
- rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ACTION,
- act, "Not supported action.");
- return -rte_errno;
- }
+ ret = ci_flow_check_actions(actions, &ac_param, &parsed_actions, error);
+ if (ret)
+ return ret;
+ first = parsed_actions.actions[0];
+ /* can be NULL */
+ second = parsed_actions.actions[1];
- if (act->type == RTE_FLOW_ACTION_TYPE_VF) {
- act_vf = act->conf;
- filter->vf_id = act_vf->id;
+ /* first action must be PF or VF */
+ if (first->type == RTE_FLOW_ACTION_TYPE_VF) {
+ const struct rte_flow_action_vf *vf = first->conf;
+ if (vf->id >= pf->vf_num) {
+ rte_flow_error_set(error, EINVAL,
+ RTE_FLOW_ERROR_TYPE_ACTION, first,
+ "Invalid VF ID for tunnel filter");
+ return -rte_errno;
+ }
+ filter->vf_id = vf->id;
filter->is_to_vf = 1;
- if (filter->vf_id >= pf->vf_num) {
- rte_flow_error_set(error, EINVAL,
- RTE_FLOW_ERROR_TYPE_ACTION,
- act, "Invalid VF ID for tunnel filter");
- return -rte_errno;
- }
+ } else if (first->type != RTE_FLOW_ACTION_TYPE_PF) {
+ return rte_flow_error_set(error, EINVAL,
+ RTE_FLOW_ERROR_TYPE_ACTION, first,
+ "Unsupported action");
}
- /* Check if the next non-void item is QUEUE */
- index++;
- NEXT_ITEM_OF_ACTION(act, actions, index);
- if (act->type == RTE_FLOW_ACTION_TYPE_QUEUE) {
- act_q = act->conf;
- filter->queue_id = act_q->index;
- if ((!filter->is_to_vf) &&
- (filter->queue_id >= pf->dev_data->nb_rx_queues)) {
- rte_flow_error_set(error, EINVAL,
- RTE_FLOW_ERROR_TYPE_ACTION,
- act, "Invalid queue ID for tunnel filter");
- return -rte_errno;
- } else if (filter->is_to_vf &&
- (filter->queue_id >= pf->vf_nb_qps)) {
- rte_flow_error_set(error, EINVAL,
- RTE_FLOW_ERROR_TYPE_ACTION,
- act, "Invalid queue ID for tunnel filter");
- return -rte_errno;
- }
- }
+ /* check if second action is QUEUE */
+ if (second == NULL)
+ return 0;
- /* Check if the next non-void item is END */
- index++;
- NEXT_ITEM_OF_ACTION(act, actions, index);
- if (act->type != RTE_FLOW_ACTION_TYPE_END) {
- rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ACTION,
- act, "Not supported action.");
- return -rte_errno;
+ act_q = second->conf;
+ /* check queue ID for PF flow */
+ if (!filter->is_to_vf && act_q->index >= pf->dev_data->nb_rx_queues) {
+ return rte_flow_error_set(error, EINVAL,
+ RTE_FLOW_ERROR_TYPE_ACTION_CONF, act_q,
+ "Invalid queue ID for tunnel filter");
+ }
+ /* check queue ID for VF flow */
+ if (filter->is_to_vf && act_q->index >= pf->vf_nb_qps) {
+ return rte_flow_error_set(error, EINVAL,
+ RTE_FLOW_ERROR_TYPE_ACTION_CONF, act_q,
+ "Invalid queue ID for tunnel filter");
}
+ filter->queue_id = act_q->index;
return 0;
}
--
2.47.3
More information about the dev
mailing list