src/dpdk/drivers/net/enic/enic_flow.c
static int
enic_copy_action_v2(struct enic *enic,
		    const struct rte_flow_action actions[],
		    struct filter_action_v2 *enic_action)
{
	enum { FATE = 1, MARK = 2, };
	uint32_t overlap = 0;
	bool passthru = false;

	ENICPMD_FUNC_TRACE();

	for (; actions->type != RTE_FLOW_ACTION_TYPE_END; actions++) {
		switch (actions->type) {
		case RTE_FLOW_ACTION_TYPE_QUEUE: {
			const struct rte_flow_action_queue *queue =
				(const struct rte_flow_action_queue *)
				actions->conf;

			if (overlap & FATE)
				return ENOTSUP;
			overlap |= FATE;
			enic_action->rq_idx =
				enic_rte_rq_idx_to_sop_idx(queue->index);
			enic_action->flags |= FILTER_ACTION_RQ_STEERING_FLAG;
			break;
		}
		case RTE_FLOW_ACTION_TYPE_MARK: {
			const struct rte_flow_action_mark *mark =
				(const struct rte_flow_action_mark *)
				actions->conf;
			if (enic->use_noscatter_vec_rx_handler)
				return ENOTSUP;
			if (overlap & MARK)
				return ENOTSUP;
			overlap |= MARK;
			/*
			 * Map mark ID (32-bit) to filter ID (16-bit):
			 * - Reject values > 16 bits
			 * - Filter ID 0 is reserved for filters that steer
			 *   but not mark. So add 1 to the mark ID to avoid
			 *   using 0.
			 * - Filter ID (ENIC_MAGIC_FILTER_ID = 0xffff) is
			 *   reserved for the "flag" action below.
			 */
			if (mark->id >= ENIC_MAGIC_FILTER_ID - 1)
				return EINVAL;
			enic_action->filter_id = mark->id + 1;
			enic_action->flags |= FILTER_ACTION_FILTER_ID_FLAG;
			break;
		}
		case RTE_FLOW_ACTION_TYPE_FLAG: {
			if (enic->use_noscatter_vec_rx_handler)
				return ENOTSUP;
			if (overlap & MARK)
				return ENOTSUP;
			overlap |= MARK;
			/* ENIC_MAGIC_FILTER_ID is reserved for flagging */
			enic_action->filter_id = ENIC_MAGIC_FILTER_ID;
			enic_action->flags |= FILTER_ACTION_FILTER_ID_FLAG;
			break;
		}
		case RTE_FLOW_ACTION_TYPE_DROP: {
			if (overlap & FATE)
				return ENOTSUP;
			overlap |= FATE;
			enic_action->flags |= FILTER_ACTION_DROP_FLAG;
			break;
		}
		case RTE_FLOW_ACTION_TYPE_RSS: {
			const struct rte_flow_action_rss *rss =
				(const struct rte_flow_action_rss *)
				actions->conf;
			bool allow;
			uint16_t i;

			/*
			 * Hardware does not support general RSS actions, but
			 * we can still support the dummy one that is used to
			 * "receive normally".
			 */
			allow = rss->func == RTE_ETH_HASH_FUNCTION_DEFAULT &&
				rss->level == 0 &&
				(rss->types == 0 ||
				 rss->types == enic->rss_hf) &&
				rss->queue_num == enic->rq_count &&
				rss->key_len == 0;
			/* Identity queue map is ok */
			for (i = 0; i < rss->queue_num; i++)
				allow = allow && (i == rss->queue[i]);
			if (!allow)
				return ENOTSUP;
			if (overlap & FATE)
				return ENOTSUP;
			/* Need MARK or FLAG */
			if (!(overlap & MARK))
				return ENOTSUP;
			overlap |= FATE;
			break;
		}
		case RTE_FLOW_ACTION_TYPE_PASSTHRU: {
			/*
			 * Like RSS above, PASSTHRU + MARK may be used to
			 * "mark and then receive normally". MARK usually comes
			 * after PASSTHRU, so remember we have seen passthru
			 * and check for mark later.
			 */
			if (overlap & FATE)
				return ENOTSUP;
			overlap |= FATE;
			passthru = true;
			break;
		}
		case RTE_FLOW_ACTION_TYPE_VOID:
			continue;
		default:
			RTE_ASSERT(0);
			break;
		}
	}
	/* Only PASSTHRU + MARK is allowed */
	if (passthru && !(overlap & MARK))
		return ENOTSUP;
	if (!(overlap & FATE))
		return ENOTSUP;
	enic_action->type = FILTER_ACTION_V2;
	return 0;
}
/**
 * Build the intenal version 2 NIC action structure from the provided pattern.
 * The pattern is validated as the items are copied.
 *
 * @param actions[in]
 * @param enic_action[out]
 *   NIC specfilc actions derived from the actions.
 * @param error[out]
 */
Build the intenal version 2 NIC action structure from the provided pattern.
The pattern is validated as the items are copied.

@param actions[in]
@param enic_action[out]
NIC specfilc actions derived from the actions.
@param error[out]
Build the intenal version 2 NIC action structure from the provided pattern . The pattern is validated as the items are copied . @param actions [ in ] @param enic_action [ out ] NIC specfilc actions derived from the actions . @param error [ out ]
static int
enic_copy_action_v2(struct enic *enic,
		    const struct rte_flow_action actions[],
		    struct filter_action_v2 *enic_action)
{
	enum { FATE = 1, MARK = 2, };
	uint32_t overlap = 0;
	bool passthru = false;
	ENICPMD_FUNC_TRACE();
	for (; actions->type != RTE_FLOW_ACTION_TYPE_END; actions++) {
		switch (actions->type) {
		case RTE_FLOW_ACTION_TYPE_QUEUE: {
			const struct rte_flow_action_queue *queue =
				(const struct rte_flow_action_queue *)
				actions->conf;
			if (overlap & FATE)
				return ENOTSUP;
			overlap |= FATE;
			enic_action->rq_idx =
				enic_rte_rq_idx_to_sop_idx(queue->index);
			enic_action->flags |= FILTER_ACTION_RQ_STEERING_FLAG;
			break;
		}
		case RTE_FLOW_ACTION_TYPE_MARK: {
			const struct rte_flow_action_mark *mark =
				(const struct rte_flow_action_mark *)
				actions->conf;
			if (enic->use_noscatter_vec_rx_handler)
				return ENOTSUP;
			if (overlap & MARK)
				return ENOTSUP;
			overlap |= MARK;
			if (mark->id >= ENIC_MAGIC_FILTER_ID - 1)
				return EINVAL;
			enic_action->filter_id = mark->id + 1;
			enic_action->flags |= FILTER_ACTION_FILTER_ID_FLAG;
			break;
		}
		case RTE_FLOW_ACTION_TYPE_FLAG: {
			if (enic->use_noscatter_vec_rx_handler)
				return ENOTSUP;
			if (overlap & MARK)
				return ENOTSUP;
			overlap |= MARK;
			enic_action->filter_id = ENIC_MAGIC_FILTER_ID;
			enic_action->flags |= FILTER_ACTION_FILTER_ID_FLAG;
			break;
		}
		case RTE_FLOW_ACTION_TYPE_DROP: {
			if (overlap & FATE)
				return ENOTSUP;
			overlap |= FATE;
			enic_action->flags |= FILTER_ACTION_DROP_FLAG;
			break;
		}
		case RTE_FLOW_ACTION_TYPE_RSS: {
			const struct rte_flow_action_rss *rss =
				(const struct rte_flow_action_rss *)
				actions->conf;
			bool allow;
			uint16_t i;
			allow = rss->func == RTE_ETH_HASH_FUNCTION_DEFAULT &&
				rss->level == 0 &&
				(rss->types == 0 ||
				 rss->types == enic->rss_hf) &&
				rss->queue_num == enic->rq_count &&
				rss->key_len == 0;
			for (i = 0; i < rss->queue_num; i++)
				allow = allow && (i == rss->queue[i]);
			if (!allow)
				return ENOTSUP;
			if (overlap & FATE)
				return ENOTSUP;
			if (!(overlap & MARK))
				return ENOTSUP;
			overlap |= FATE;
			break;
		}
		case RTE_FLOW_ACTION_TYPE_PASSTHRU: {
			if (overlap & FATE)
				return ENOTSUP;
			overlap |= FATE;
			passthru = true;
			break;
		}
		case RTE_FLOW_ACTION_TYPE_VOID:
			continue;
		default:
			RTE_ASSERT(0);
			break;
		}
	}
	if (passthru && !(overlap & MARK))
		return ENOTSUP;
	if (!(overlap & FATE))
		return ENOTSUP;
	enic_action->type = FILTER_ACTION_V2;
	return 0;
}
static int enic_copy_action_v2 ( struct enic * enic , const struct rte_flow_action actions [ ] , struct filter_action_v2 * enic_action ) { enum { FATE = 1 , MARK = 2 , } ; uint32_t overlap = 0 ; bool passthru = false ; ENICPMD_FUNC_TRACE ( ) ; for ( ; actions -> type != RTE_FLOW_ACTION_TYPE_END ; actions ++ ) { switch ( actions -> type ) { case RTE_FLOW_ACTION_TYPE_QUEUE : { const struct rte_flow_action_queue * queue = ( const struct rte_flow_action_queue * ) actions -> conf ; if ( overlap & FATE ) return ENOTSUP ; overlap |= FATE ; enic_action -> rq_idx = enic_rte_rq_idx_to_sop_idx ( queue -> index ) ; enic_action -> flags |= FILTER_ACTION_RQ_STEERING_FLAG ; break ; } case RTE_FLOW_ACTION_TYPE_MARK : { const struct rte_flow_action_mark * mark = ( const struct rte_flow_action_mark * ) actions -> conf ; if ( enic -> use_noscatter_vec_rx_handler ) return ENOTSUP ; if ( overlap & MARK ) return ENOTSUP ; overlap |= MARK ; if ( mark -> id >= ENIC_MAGIC_FILTER_ID - 1 ) return EINVAL ; enic_action -> filter_id = mark -> id + 1 ; enic_action -> flags |= FILTER_ACTION_FILTER_ID_FLAG ; break ; } case RTE_FLOW_ACTION_TYPE_FLAG : { if ( enic -> use_noscatter_vec_rx_handler ) return ENOTSUP ; if ( overlap & MARK ) return ENOTSUP ; overlap |= MARK ; enic_action -> filter_id = ENIC_MAGIC_FILTER_ID ; enic_action -> flags |= FILTER_ACTION_FILTER_ID_FLAG ; break ; } case RTE_FLOW_ACTION_TYPE_DROP : { if ( overlap & FATE ) return ENOTSUP ; overlap |= FATE ; enic_action -> flags |= FILTER_ACTION_DROP_FLAG ; break ; } case RTE_FLOW_ACTION_TYPE_RSS : { const struct rte_flow_action_rss * rss = ( const struct rte_flow_action_rss * ) actions -> conf ; bool allow ; uint16_t i ; allow = rss -> func == RTE_ETH_HASH_FUNCTION_DEFAULT && rss -> level == 0 && ( rss -> types == 0 || rss -> types == enic -> rss_hf ) && rss -> queue_num == enic -> rq_count && rss -> key_len == 0 ; for ( i = 0 ; i < rss -> queue_num ; i ++ ) allow = allow && ( i == rss -> queue [ i ] ) ; if ( ! allow ) return ENOTSUP ; if ( overlap & FATE ) return ENOTSUP ; if ( ! ( overlap & MARK ) ) return ENOTSUP ; overlap |= FATE ; break ; } case RTE_FLOW_ACTION_TYPE_PASSTHRU : { if ( overlap & FATE ) return ENOTSUP ; overlap |= FATE ; passthru = true ; break ; } case RTE_FLOW_ACTION_TYPE_VOID : continue ; default : RTE_ASSERT ( 0 ) ; break ; } } if ( passthru && ! ( overlap & MARK ) ) return ENOTSUP ; if ( ! ( overlap & FATE ) ) return ENOTSUP ; enic_action -> type = FILTER_ACTION_V2 ; return 0 ; }
Build the intenal version 2 NIC action structure from the provided pattern.
Build the intenal version 2 NIC action structure from the provided pattern .
/*
			 * Map mark ID (32-bit) to filter ID (16-bit):
			 * - Reject values > 16 bits
			 * - Filter ID 0 is reserved for filters that steer
			 *   but not mark. So add 1 to the mark ID to avoid
			 *   using 0.
			 * - Filter ID (ENIC_MAGIC_FILTER_ID = 0xffff) is
			 *   reserved for the "flag" action below.
			 */ /* ENIC_MAGIC_FILTER_ID is reserved for flagging */ /*
			 * Hardware does not support general RSS actions, but
			 * we can still support the dummy one that is used to
			 * "receive normally".
			 */ /* Identity queue map is ok */ /* Need MARK or FLAG */ /*
			 * Like RSS above, PASSTHRU + MARK may be used to
			 * "mark and then receive normally". MARK usually comes
			 * after PASSTHRU, so remember we have seen passthru
			 * and check for mark later.
			 */ /* Only PASSTHRU + MARK is allowed */