else
ret = RTE_FLOW_ITEM_TYPE_END;
break;
+ case RTE_FLOW_ITEM_TYPE_GENEVE:
+ ether_type_m = item->mask ?
+ ((const struct rte_flow_item_geneve *)
+ (item->mask))->protocol :
+ rte_flow_item_geneve_mask.protocol;
+ ether_type = ((const struct rte_flow_item_geneve *)
+ (item->spec))->protocol;
+ ether_type_m = rte_be_to_cpu_16(ether_type_m);
+ ether_type = rte_be_to_cpu_16(ether_type);
+ switch (ether_type_m & ether_type) {
+ case RTE_ETHER_TYPE_TEB:
+ ret = RTE_FLOW_ITEM_TYPE_ETH;
+ break;
+ case RTE_ETHER_TYPE_IPV4:
+ ret = RTE_FLOW_ITEM_TYPE_IPV4;
+ break;
+ case RTE_ETHER_TYPE_IPV6:
+ ret = RTE_FLOW_ITEM_TYPE_IPV6;
+ break;
+ default:
+ ret = RTE_FLOW_ITEM_TYPE_END;
+ }
+ break;
default:
ret = RTE_FLOW_ITEM_TYPE_VOID;
break;
MLX5_EXPANSION_IPV6_UDP,
MLX5_EXPANSION_IPV6_TCP,
MLX5_EXPANSION_IPV6_FRAG_EXT,
- MLX5_EXPANSION_GTP
+ MLX5_EXPANSION_GTP,
+ MLX5_EXPANSION_GENEVE,
};
/** Supported expansion of items. */
.next = MLX5_FLOW_EXPAND_RSS_NEXT(MLX5_EXPANSION_VXLAN,
MLX5_EXPANSION_VXLAN_GPE,
MLX5_EXPANSION_MPLS,
+ MLX5_EXPANSION_GENEVE,
MLX5_EXPANSION_GTP),
.type = RTE_FLOW_ITEM_TYPE_UDP,
.rss_types = RTE_ETH_RSS_NONFRAG_IPV4_UDP,
.next = MLX5_FLOW_EXPAND_RSS_NEXT(MLX5_EXPANSION_VXLAN,
MLX5_EXPANSION_VXLAN_GPE,
MLX5_EXPANSION_MPLS,
+ MLX5_EXPANSION_GENEVE,
MLX5_EXPANSION_GTP),
.type = RTE_FLOW_ITEM_TYPE_UDP,
.rss_types = RTE_ETH_RSS_NONFRAG_IPV6_UDP,
.type = RTE_FLOW_ITEM_TYPE_VXLAN_GPE,
},
[MLX5_EXPANSION_GRE] = {
- .next = MLX5_FLOW_EXPAND_RSS_NEXT(MLX5_EXPANSION_IPV4,
+ .next = MLX5_FLOW_EXPAND_RSS_NEXT(MLX5_EXPANSION_ETH,
+ MLX5_EXPANSION_IPV4,
MLX5_EXPANSION_IPV6,
MLX5_EXPANSION_GRE_KEY,
MLX5_EXPANSION_MPLS),
MLX5_EXPANSION_IPV6),
.type = RTE_FLOW_ITEM_TYPE_GTP,
},
+ [MLX5_EXPANSION_GENEVE] = {
+ .next = MLX5_FLOW_EXPAND_RSS_NEXT(MLX5_EXPANSION_ETH,
+ MLX5_EXPANSION_IPV4,
+ MLX5_EXPANSION_IPV6),
+ .type = RTE_FLOW_ITEM_TYPE_GENEVE,
+ },
};
static struct rte_flow_action_handle *
case MLX5_MTR_COLOR:
case MLX5_ASO_FLOW_HIT:
case MLX5_ASO_CONNTRACK:
+ case MLX5_SAMPLE_ID:
/* All features use the same REG_C. */
MLX5_ASSERT(priv->mtr_color_reg != REG_NON);
return priv->mtr_color_reg;
* Pointer to the Q/RSS action.
* @param[in] actions_n
* Number of original actions.
+ * @param[in] mtr_sfx
+ * Check if it is in meter suffix table.
* @param[out] error
* Perform verbose error reporting if not NULL.
*
struct rte_flow_action *split_actions,
const struct rte_flow_action *actions,
const struct rte_flow_action *qrss,
- int actions_n, struct rte_flow_error *error)
+ int actions_n, int mtr_sfx,
+ struct rte_flow_error *error)
{
struct mlx5_priv *priv = dev->data->dev_private;
struct mlx5_rte_flow_action_set_tag *set_tag;
* - Add jump to mreg CP_TBL.
* As a result, there will be one more action.
*/
- ++actions_n;
memcpy(split_actions, actions, sizeof(*split_actions) * actions_n);
+ /* Count MLX5_RTE_FLOW_ACTION_TYPE_TAG. */
+ ++actions_n;
set_tag = (void *)(split_actions + actions_n);
/*
- * If tag action is not set to void(it means we are not the meter
- * suffix flow), add the tag action. Since meter suffix flow already
- * has the tag added.
+ * If we are not the meter suffix flow, add the tag action.
+ * Since meter suffix flow already has the tag added.
*/
- if (split_actions[qrss_idx].type != RTE_FLOW_ACTION_TYPE_VOID) {
+ if (!mtr_sfx) {
/*
* Allocate the new subflow ID. This one is unique within
* device and not shared with representors. Otherwise,
MLX5_RTE_FLOW_ACTION_TYPE_TAG,
.conf = set_tag,
};
+ } else {
+ /*
+ * If we are the suffix flow of meter, tag already exist.
+ * Set the QUEUE/RSS action to void.
+ */
+ split_actions[qrss_idx].type = RTE_FLOW_ACTION_TYPE_VOID;
}
/* JUMP action to jump to mreg copy table (CP_TBL). */
jump = (void *)(set_tag + 1);
/* Prepare the prefix tag action. */
append_index++;
set_tag = (void *)(actions_pre + actions_n + append_index);
- ret = mlx5_flow_get_reg_id(dev, MLX5_APP_TAG, 0, error);
+ ret = mlx5_flow_get_reg_id(dev, MLX5_SAMPLE_ID, 0, error);
if (ret < 0)
return ret;
mlx5_ipool_malloc(priv->sh->ipool
RTE_FLOW_ERROR_TYPE_ACTION,
NULL, "no memory to split "
"metadata flow");
- /*
- * If we are the suffix flow of meter, tag already exist.
- * Set the tag action to void.
- */
- if (mtr_sfx)
- ext_actions[qrss - actions].type =
- RTE_FLOW_ACTION_TYPE_VOID;
- else
- ext_actions[qrss - actions].type =
- (enum rte_flow_action_type)
- MLX5_RTE_FLOW_ACTION_TYPE_TAG;
/*
* Create the new actions list with removed Q/RSS action
* and appended set tag and jump to register copy table
* in advance, because it is needed for set tag action.
*/
qrss_id = flow_mreg_split_qrss_prep(dev, ext_actions, actions,
- qrss, actions_n, error);
+ qrss, actions_n,
+ mtr_sfx, error);
if (!mtr_sfx && !qrss_id) {
ret = -rte_errno;
goto exit;
static int
mlx5_flow_create_counter_stat_mem_mng(struct mlx5_dev_ctx_shared *sh)
{
- struct mlx5_devx_mkey_attr mkey_attr;
struct mlx5_counter_stats_mem_mng *mem_mng;
volatile struct flow_counter_stats *raw_data;
int raws_n = MLX5_CNT_CONTAINER_RESIZE + MLX5_MAX_PENDING_QUERIES;
sizeof(struct mlx5_counter_stats_mem_mng);
size_t pgsize = rte_mem_page_size();
uint8_t *mem;
+ int ret;
int i;
if (pgsize == (size_t)-1) {
}
mem_mng = (struct mlx5_counter_stats_mem_mng *)(mem + size) - 1;
size = sizeof(*raw_data) * MLX5_COUNTERS_PER_POOL * raws_n;
- mem_mng->umem = mlx5_os_umem_reg(sh->cdev->ctx, mem, size,
- IBV_ACCESS_LOCAL_WRITE);
- if (!mem_mng->umem) {
- rte_errno = errno;
- mlx5_free(mem);
- return -rte_errno;
- }
- memset(&mkey_attr, 0, sizeof(mkey_attr));
- mkey_attr.addr = (uintptr_t)mem;
- mkey_attr.size = size;
- mkey_attr.umem_id = mlx5_os_get_umem_id(mem_mng->umem);
- mkey_attr.pd = sh->cdev->pdn;
- mkey_attr.relaxed_ordering_write = sh->cmng.relaxed_ordering_write;
- mkey_attr.relaxed_ordering_read = sh->cmng.relaxed_ordering_read;
- mem_mng->dm = mlx5_devx_cmd_mkey_create(sh->cdev->ctx, &mkey_attr);
- if (!mem_mng->dm) {
- mlx5_os_umem_dereg(mem_mng->umem);
+ ret = mlx5_os_wrapped_mkey_create(sh->cdev->ctx, sh->cdev->pd,
+ sh->cdev->pdn, mem, size,
+ &mem_mng->wm);
+ if (ret) {
rte_errno = errno;
mlx5_free(mem);
return -rte_errno;
ret = mlx5_devx_cmd_flow_counter_query(pool->min_dcs, 0,
MLX5_COUNTERS_PER_POOL,
NULL, NULL,
- pool->raw_hw->mem_mng->dm->id,
+ pool->raw_hw->mem_mng->wm.lkey,
(void *)(uintptr_t)
pool->raw_hw->data,
sh->devx_comp,
return err;
}
-static inline bool
+static inline int
mlx5_flow_tunnel_validate(struct rte_eth_dev *dev,
struct rte_flow_tunnel *tunnel,
- const char *err_msg)
+ struct rte_flow_error *error)
{
- err_msg = NULL;
- if (!is_tunnel_offload_active(dev)) {
- err_msg = "tunnel offload was not activated";
- goto out;
- } else if (!tunnel) {
- err_msg = "no application tunnel";
- goto out;
- }
+ struct mlx5_priv *priv = dev->data->dev_private;
+ if (!priv->config.dv_flow_en)
+ return rte_flow_error_set(error, ENOTSUP,
+ RTE_FLOW_ERROR_TYPE_ACTION_CONF, NULL,
+ "flow DV interface is off");
+ if (!is_tunnel_offload_active(dev))
+ return rte_flow_error_set(error, ENOTSUP,
+ RTE_FLOW_ERROR_TYPE_ACTION_CONF, NULL,
+ "tunnel offload was not activated");
+ if (!tunnel)
+ return rte_flow_error_set(error, EINVAL,
+ RTE_FLOW_ERROR_TYPE_ACTION_CONF, NULL,
+ "no application tunnel");
switch (tunnel->type) {
default:
- err_msg = "unsupported tunnel type";
- goto out;
+ return rte_flow_error_set(error, EINVAL,
+ RTE_FLOW_ERROR_TYPE_ACTION_CONF, NULL,
+ "unsupported tunnel type");
case RTE_FLOW_ITEM_TYPE_VXLAN:
case RTE_FLOW_ITEM_TYPE_GRE:
case RTE_FLOW_ITEM_TYPE_NVGRE:
case RTE_FLOW_ITEM_TYPE_GENEVE:
break;
}
-
-out:
- return !err_msg;
+ return 0;
}
static int
uint32_t *num_of_actions,
struct rte_flow_error *error)
{
- int ret;
struct mlx5_flow_tunnel *tunnel;
- const char *err_msg = NULL;
- bool verdict = mlx5_flow_tunnel_validate(dev, app_tunnel, err_msg);
+ int ret = mlx5_flow_tunnel_validate(dev, app_tunnel, error);
- if (!verdict)
- return rte_flow_error_set(error, EINVAL,
- RTE_FLOW_ERROR_TYPE_ACTION_CONF, NULL,
- err_msg);
+ if (ret)
+ return ret;
ret = mlx5_get_flow_tunnel(dev, app_tunnel, &tunnel);
if (ret < 0) {
return rte_flow_error_set(error, ret,
uint32_t *num_of_items,
struct rte_flow_error *error)
{
- int ret;
struct mlx5_flow_tunnel *tunnel;
- const char *err_msg = NULL;
- bool verdict = mlx5_flow_tunnel_validate(dev, app_tunnel, err_msg);
+ int ret = mlx5_flow_tunnel_validate(dev, app_tunnel, error);
- if (!verdict)
- return rte_flow_error_set(error, EINVAL,
- RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
- err_msg);
+ if (ret)
+ return ret;
ret = mlx5_get_flow_tunnel(dev, app_tunnel, &tunnel);
if (ret < 0) {
return rte_flow_error_set(error, ret,