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 <[email protected]> --- 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 d8c8654cfa..dd3bf5822a 100644 --- a/drivers/net/intel/i40e/i40e_flow.c +++ b/drivers/net/intel/i40e/i40e_flow.c @@ -1103,15 +1103,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) @@ -2514,61 +2505,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

