Use the common flow action checking parsing infrastructure for checking flow actions for flow director filter.
Signed-off-by: Anatoly Burakov <[email protected]> --- drivers/net/intel/i40e/i40e_flow.c | 139 ++++++++++++++++------------- 1 file changed, 76 insertions(+), 63 deletions(-) diff --git a/drivers/net/intel/i40e/i40e_flow.c b/drivers/net/intel/i40e/i40e_flow.c index 0e9880e9ce..d8c8654cfa 100644 --- a/drivers/net/intel/i40e/i40e_flow.c +++ b/drivers/net/intel/i40e/i40e_flow.c @@ -2371,28 +2371,49 @@ i40e_flow_parse_fdir_action(struct rte_eth_dev *dev, struct i40e_fdir_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_mark *mark_spec = NULL; - 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_DROP, + RTE_FLOW_ACTION_TYPE_PASSTHRU, + RTE_FLOW_ACTION_TYPE_MARK, + RTE_FLOW_ACTION_TYPE_FLAG, + RTE_FLOW_ACTION_TYPE_RSS, + 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 QUEUE or DROP or PASSTHRU. */ - NEXT_ITEM_OF_ACTION(act, actions, index); - switch (act->type) { + 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]; + + switch (first->type) { case RTE_FLOW_ACTION_TYPE_QUEUE: - act_q = act->conf; + { + const struct rte_flow_action_queue *act_q = first->conf; + /* check against PF constraints */ + if (!filter->input.flow_ext.is_vf && act_q->index >= pf->dev_data->nb_rx_queues) { + return rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_ACTION, first, + "Invalid queue ID for FDIR"); + } + /* check against VF constraints */ + if (filter->input.flow_ext.is_vf && act_q->index >= pf->vf_nb_qps) { + return rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_ACTION, first, + "Invalid queue ID for FDIR"); + } filter->action.rx_queue = act_q->index; - if ((!filter->input.flow_ext.is_vf && - filter->action.rx_queue >= pf->dev_data->nb_rx_queues) || - (filter->input.flow_ext.is_vf && - filter->action.rx_queue >= pf->vf_nb_qps)) { - rte_flow_error_set(error, EINVAL, - RTE_FLOW_ERROR_TYPE_ACTION, act, - "Invalid queue ID for FDIR."); - return -rte_errno; - } filter->action.behavior = I40E_FDIR_ACCEPT; break; + } case RTE_FLOW_ACTION_TYPE_DROP: filter->action.behavior = I40E_FDIR_REJECT; break; @@ -2400,69 +2421,61 @@ i40e_flow_parse_fdir_action(struct rte_eth_dev *dev, filter->action.behavior = I40E_FDIR_PASSTHRU; break; case RTE_FLOW_ACTION_TYPE_MARK: + { + const struct rte_flow_action_mark *act_m = first->conf; filter->action.behavior = I40E_FDIR_PASSTHRU; - mark_spec = act->conf; filter->action.report_status = I40E_FDIR_REPORT_ID; - filter->soft_id = mark_spec->id; - break; + filter->soft_id = act_m->id; + break; + } default: - rte_flow_error_set(error, EINVAL, - RTE_FLOW_ERROR_TYPE_ACTION, act, - "Invalid action."); - return -rte_errno; + return rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_ACTION, first, + "Invalid first action for FDIR"); } - /* Check if the next non-void item is MARK or FLAG or END. */ - index++; - NEXT_ITEM_OF_ACTION(act, actions, index); - switch (act->type) { + /* do we have another? */ + if (second == NULL) + return 0; + + switch (second->type) { case RTE_FLOW_ACTION_TYPE_MARK: - if (mark_spec) { - /* Double MARK actions requested */ - rte_flow_error_set(error, EINVAL, - RTE_FLOW_ERROR_TYPE_ACTION, act, - "Invalid action."); - return -rte_errno; + { + const struct rte_flow_action_mark *act_m = second->conf; + /* only one mark action can be specified */ + if (first->type == RTE_FLOW_ACTION_TYPE_MARK) { + return rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_ACTION, second, + "Invalid second action for FDIR"); } - mark_spec = act->conf; filter->action.report_status = I40E_FDIR_REPORT_ID; - filter->soft_id = mark_spec->id; + filter->soft_id = act_m->id; break; + } case RTE_FLOW_ACTION_TYPE_FLAG: - if (mark_spec) { - /* MARK + FLAG not supported */ - rte_flow_error_set(error, EINVAL, - RTE_FLOW_ERROR_TYPE_ACTION, act, - "Invalid action."); - return -rte_errno; + { + /* mark + flag is unsupported */ + if (first->type == RTE_FLOW_ACTION_TYPE_MARK) { + return rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_ACTION, second, + "Invalid second action for FDIR"); } filter->action.report_status = I40E_FDIR_NO_REPORT_STATUS; break; + } case RTE_FLOW_ACTION_TYPE_RSS: - if (filter->action.behavior != I40E_FDIR_PASSTHRU) { - /* RSS filter won't be next if FDIR did not pass thru */ - rte_flow_error_set(error, EINVAL, - RTE_FLOW_ERROR_TYPE_ACTION, act, - "Invalid action."); - return -rte_errno; + /* RSS filter only can be after passthru or mark */ + if (first->type != RTE_FLOW_ACTION_TYPE_PASSTHRU && + first->type != RTE_FLOW_ACTION_TYPE_MARK) { + return rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_ACTION, second, + "Invalid second action for FDIR"); } break; - case RTE_FLOW_ACTION_TYPE_END: - return 0; default: - rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ACTION, - act, "Invalid action."); - return -rte_errno; - } - - /* 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, "Invalid action."); - return -rte_errno; + return rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_ACTION, second, + "Invalid second action for FDIR"); } return 0; -- 2.47.3

