src/dpdk/drivers/net/mvpp2/mrvl_flow.c
static int
mrvl_flow_parse_actions(struct mrvl_priv *priv,
			const struct rte_flow_action actions[],
			struct rte_flow *flow,
			struct rte_flow_error *error)
{
	const struct rte_flow_action *action = actions;
	int specified = 0;

	for (; action->type != RTE_FLOW_ACTION_TYPE_END; action++) {
		if (action->type == RTE_FLOW_ACTION_TYPE_VOID)
			continue;

		if (action->type == RTE_FLOW_ACTION_TYPE_DROP) {
			flow->cos.ppio = priv->ppio;
			flow->cos.tc = 0;
			flow->action.type = PP2_CLS_TBL_ACT_DROP;
			flow->action.cos = &flow->cos;
			specified++;
		} else if (action->type == RTE_FLOW_ACTION_TYPE_QUEUE) {
			const struct rte_flow_action_queue *q =
				(const struct rte_flow_action_queue *)
				action->conf;

			if (q->index > priv->nb_rx_queues) {
				rte_flow_error_set(error, EINVAL,
						RTE_FLOW_ERROR_TYPE_ACTION,
						NULL,
						"Queue index out of range");
				return -rte_errno;
			}

			if (priv->rxq_map[q->index].tc == MRVL_UNKNOWN_TC) {
				/*
				 * Unknown TC mapping, mapping will not have
				 * a correct queue.
				 */
				MRVL_LOG(ERR,
					"Unknown TC mapping for queue %hu eth%hhu",
					q->index, priv->ppio_id);

				rte_flow_error_set(error, EFAULT,
						RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
						NULL, NULL);
				return -rte_errno;
			}

			MRVL_LOG(DEBUG,
				"Action: Assign packets to queue %d, tc:%d, q:%d",
				q->index, priv->rxq_map[q->index].tc,
				priv->rxq_map[q->index].inq);

			flow->cos.ppio = priv->ppio;
			flow->cos.tc = priv->rxq_map[q->index].tc;
			flow->action.type = PP2_CLS_TBL_ACT_DONE;
			flow->action.cos = &flow->cos;
			specified++;
		} else if (action->type == RTE_FLOW_ACTION_TYPE_METER) {
			const struct rte_flow_action_meter *meter;
			struct mrvl_mtr *mtr;

			meter = action->conf;
			if (!meter)
				return -rte_flow_error_set(error, EINVAL,
						RTE_FLOW_ERROR_TYPE_ACTION,
						NULL, "Invalid meter\n");

			LIST_FOREACH(mtr, &priv->mtrs, next)
				if (mtr->mtr_id == meter->mtr_id)
					break;

			if (!mtr)
				return -rte_flow_error_set(error, EINVAL,
						RTE_FLOW_ERROR_TYPE_ACTION,
						NULL,
						"Meter id does not exist\n");

			if (!mtr->shared && mtr->refcnt)
				return -rte_flow_error_set(error, EPERM,
						RTE_FLOW_ERROR_TYPE_ACTION,
						NULL,
						"Meter cannot be shared\n");

			/*
			 * In case cos has already been set
			 * do not modify it.
			 */
			if (!flow->cos.ppio) {
				flow->cos.ppio = priv->ppio;
				flow->cos.tc = 0;
			}

			flow->action.type = PP2_CLS_TBL_ACT_DONE;
			flow->action.cos = &flow->cos;
			flow->action.plcr = mtr->enabled ? mtr->plcr : NULL;
			flow->mtr = mtr;
			mtr->refcnt++;
			specified++;
		} else {
			rte_flow_error_set(error, ENOTSUP,
					   RTE_FLOW_ERROR_TYPE_ACTION, NULL,
					   "Action not supported");
			return -rte_errno;
		}
	}

	if (!specified) {
		rte_flow_error_set(error, EINVAL,
				   RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
				   "Action not specified");
		return -rte_errno;
	}

	return 0;
}
/**
 * Parse flow actions.
 *
 * @param priv Pointer to the port's private data.
 * @param actions Pointer the action table.
 * @param flow Pointer to the flow.
 * @param error Pointer to the flow error.
 * @returns 0 in case of success, negative value otherwise.
 */
Parse flow actions.
@param priv Pointer to the port's private data.
@param actions Pointer the action table.
@param flow Pointer to the flow.
@param error Pointer to the flow error.
@returns 0 in case of success, negative value otherwise.
Parse flow actions . @param priv Pointer to the port ' s private data . @param actions Pointer the action table . @param flow Pointer to the flow . @param error Pointer to the flow error . @returns 0 in case of success negative value otherwise .
static int
mrvl_flow_parse_actions(struct mrvl_priv *priv,
			const struct rte_flow_action actions[],
			struct rte_flow *flow,
			struct rte_flow_error *error)
{
	const struct rte_flow_action *action = actions;
	int specified = 0;
	for (; action->type != RTE_FLOW_ACTION_TYPE_END; action++) {
		if (action->type == RTE_FLOW_ACTION_TYPE_VOID)
			continue;
		if (action->type == RTE_FLOW_ACTION_TYPE_DROP) {
			flow->cos.ppio = priv->ppio;
			flow->cos.tc = 0;
			flow->action.type = PP2_CLS_TBL_ACT_DROP;
			flow->action.cos = &flow->cos;
			specified++;
		} else if (action->type == RTE_FLOW_ACTION_TYPE_QUEUE) {
			const struct rte_flow_action_queue *q =
				(const struct rte_flow_action_queue *)
				action->conf;
			if (q->index > priv->nb_rx_queues) {
				rte_flow_error_set(error, EINVAL,
						RTE_FLOW_ERROR_TYPE_ACTION,
						NULL,
						"Queue index out of range");
				return -rte_errno;
			}
			if (priv->rxq_map[q->index].tc == MRVL_UNKNOWN_TC) {
				MRVL_LOG(ERR,
					"Unknown TC mapping for queue %hu eth%hhu",
					q->index, priv->ppio_id);
				rte_flow_error_set(error, EFAULT,
						RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
						NULL, NULL);
				return -rte_errno;
			}
			MRVL_LOG(DEBUG,
				"Action: Assign packets to queue %d, tc:%d, q:%d",
				q->index, priv->rxq_map[q->index].tc,
				priv->rxq_map[q->index].inq);
			flow->cos.ppio = priv->ppio;
			flow->cos.tc = priv->rxq_map[q->index].tc;
			flow->action.type = PP2_CLS_TBL_ACT_DONE;
			flow->action.cos = &flow->cos;
			specified++;
		} else if (action->type == RTE_FLOW_ACTION_TYPE_METER) {
			const struct rte_flow_action_meter *meter;
			struct mrvl_mtr *mtr;
			meter = action->conf;
			if (!meter)
				return -rte_flow_error_set(error, EINVAL,
						RTE_FLOW_ERROR_TYPE_ACTION,
						NULL, "Invalid meter\n");
			LIST_FOREACH(mtr, &priv->mtrs, next)
				if (mtr->mtr_id == meter->mtr_id)
					break;
			if (!mtr)
				return -rte_flow_error_set(error, EINVAL,
						RTE_FLOW_ERROR_TYPE_ACTION,
						NULL,
						"Meter id does not exist\n");
			if (!mtr->shared && mtr->refcnt)
				return -rte_flow_error_set(error, EPERM,
						RTE_FLOW_ERROR_TYPE_ACTION,
						NULL,
						"Meter cannot be shared\n");
			if (!flow->cos.ppio) {
				flow->cos.ppio = priv->ppio;
				flow->cos.tc = 0;
			}
			flow->action.type = PP2_CLS_TBL_ACT_DONE;
			flow->action.cos = &flow->cos;
			flow->action.plcr = mtr->enabled ? mtr->plcr : NULL;
			flow->mtr = mtr;
			mtr->refcnt++;
			specified++;
		} else {
			rte_flow_error_set(error, ENOTSUP,
					   RTE_FLOW_ERROR_TYPE_ACTION, NULL,
					   "Action not supported");
			return -rte_errno;
		}
	}
	if (!specified) {
		rte_flow_error_set(error, EINVAL,
				   RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
				   "Action not specified");
		return -rte_errno;
	}
	return 0;
}
static int mrvl_flow_parse_actions ( struct mrvl_priv * priv , const struct rte_flow_action actions [ ] , struct rte_flow * flow , struct rte_flow_error * error ) { const struct rte_flow_action * action = actions ; int specified = 0 ; for ( ; action -> type != RTE_FLOW_ACTION_TYPE_END ; action ++ ) { if ( action -> type == RTE_FLOW_ACTION_TYPE_VOID ) continue ; if ( action -> type == RTE_FLOW_ACTION_TYPE_DROP ) { flow -> cos . ppio = priv -> ppio ; flow -> cos . tc = 0 ; flow -> action . type = PP2_CLS_TBL_ACT_DROP ; flow -> action . cos = & flow -> cos ; specified ++ ; } else if ( action -> type == RTE_FLOW_ACTION_TYPE_QUEUE ) { const struct rte_flow_action_queue * q = ( const struct rte_flow_action_queue * ) action -> conf ; if ( q -> index > priv -> nb_rx_queues ) { rte_flow_error_set ( error , EINVAL , RTE_FLOW_ERROR_TYPE_ACTION , NULL , " " ) ; return - rte_errno ; } if ( priv -> rxq_map [ q -> index ] . tc == MRVL_UNKNOWN_TC ) { MRVL_LOG ( ERR , " " , q -> index , priv -> ppio_id ) ; rte_flow_error_set ( error , EFAULT , RTE_FLOW_ERROR_TYPE_UNSPECIFIED , NULL , NULL ) ; return - rte_errno ; } MRVL_LOG ( DEBUG , " " , q -> index , priv -> rxq_map [ q -> index ] . tc , priv -> rxq_map [ q -> index ] . inq ) ; flow -> cos . ppio = priv -> ppio ; flow -> cos . tc = priv -> rxq_map [ q -> index ] . tc ; flow -> action . type = PP2_CLS_TBL_ACT_DONE ; flow -> action . cos = & flow -> cos ; specified ++ ; } else if ( action -> type == RTE_FLOW_ACTION_TYPE_METER ) { const struct rte_flow_action_meter * meter ; struct mrvl_mtr * mtr ; meter = action -> conf ; if ( ! meter ) return - rte_flow_error_set ( error , EINVAL , RTE_FLOW_ERROR_TYPE_ACTION , NULL , " \n " ) ; LIST_FOREACH ( mtr , & priv -> mtrs , next ) if ( mtr -> mtr_id == meter -> mtr_id ) break ; if ( ! mtr ) return - rte_flow_error_set ( error , EINVAL , RTE_FLOW_ERROR_TYPE_ACTION , NULL , " \n " ) ; if ( ! mtr -> shared && mtr -> refcnt ) return - rte_flow_error_set ( error , EPERM , RTE_FLOW_ERROR_TYPE_ACTION , NULL , " \n " ) ; if ( ! flow -> cos . ppio ) { flow -> cos . ppio = priv -> ppio ; flow -> cos . tc = 0 ; } flow -> action . type = PP2_CLS_TBL_ACT_DONE ; flow -> action . cos = & flow -> cos ; flow -> action . plcr = mtr -> enabled ? mtr -> plcr : NULL ; flow -> mtr = mtr ; mtr -> refcnt ++ ; specified ++ ; } else { rte_flow_error_set ( error , ENOTSUP , RTE_FLOW_ERROR_TYPE_ACTION , NULL , " " ) ; return - rte_errno ; } } if ( ! specified ) { rte_flow_error_set ( error , EINVAL , RTE_FLOW_ERROR_TYPE_UNSPECIFIED , NULL , " " ) ; return - rte_errno ; } return 0 ; }
Parse flow actions.
Parse flow actions .
/*
				 * Unknown TC mapping, mapping will not have
				 * a correct queue.
				 */ /*
			 * In case cos has already been set
			 * do not modify it.
			 */