@@ -8,7 +8,7 @@ include $(RTE_SDK)/mk/rte.vars.mk
LIB = librte_pmd_mlx5.a
LIB_GLUE = $(LIB_GLUE_BASE).$(LIB_GLUE_VERSION)
LIB_GLUE_BASE = librte_pmd_mlx5_glue.so
-LIB_GLUE_VERSION = 19.05.0
+LIB_GLUE_VERSION = 19.08.0
# Sources.
SRCS-$(CONFIG_RTE_LIBRTE_MLX5_PMD) += mlx5.c
@@ -4,7 +4,7 @@
pmd_dlopen = (get_option('ibverbs_link') == 'dlopen')
LIB_GLUE_BASE = 'librte_pmd_mlx5_glue.so'
-LIB_GLUE_VERSION = '19.05.0'
+LIB_GLUE_VERSION = '19.08.0'
LIB_GLUE = LIB_GLUE_BASE + '.' + LIB_GLUE_VERSION
if pmd_dlopen
dpdk_conf.set('RTE_IBVERBS_LINK_DLOPEN', 1)
@@ -369,6 +369,7 @@ struct mlx5_dev_spawn_data {
}
pthread_mutex_init(&sh->dv_mutex, NULL);
sh->tx_domain = domain;
+ sh->pop_vlan_action = mlx5_glue->dr_create_flow_action_pop_vlan();
#ifdef HAVE_MLX5DV_DR_ESWITCH
if (priv->config.dv_esw_en) {
domain = mlx5_glue->dr_create_domain
@@ -400,6 +401,10 @@ struct mlx5_dev_spawn_data {
mlx5_glue->dr_destroy_domain(sh->fdb_domain);
sh->fdb_domain = NULL;
}
+ if (sh->pop_vlan_action) {
+ mlx5_glue->destroy_flow_action(sh->pop_vlan_action);
+ sh->pop_vlan_action = NULL;
+ }
if (sh->esw_drop_action) {
mlx5_glue->destroy_flow_action(sh->esw_drop_action);
sh->esw_drop_action = NULL;
@@ -439,6 +444,10 @@ struct mlx5_dev_spawn_data {
mlx5_glue->dr_destroy_domain(sh->tx_domain);
sh->tx_domain = NULL;
}
+ if (sh->pop_vlan_action) {
+ mlx5_glue->destroy_flow_action(sh->pop_vlan_action);
+ sh->pop_vlan_action = NULL;
+ }
#ifdef HAVE_MLX5DV_DR_ESWITCH
if (sh->fdb_domain) {
mlx5_glue->dr_destroy_domain(sh->fdb_domain);
@@ -297,6 +297,7 @@ struct mlx5_ibv_shared {
void *tx_domain; /* TX Direct Rules name space handle. */
struct mlx5_flow_tbl_resource tx_tbl[MLX5_MAX_TABLES];
void *esw_drop_action; /* Pointer to DR E-Switch drop action. */
+ void *pop_vlan_action; /* Pointer to DR pop VLAN action. */
/* TX Direct Rules tables/ */
LIST_HEAD(matchers, mlx5_flow_dv_matcher) matchers;
LIST_HEAD(encap_decap, mlx5_flow_dv_encap_decap_resource) encaps_decaps;
@@ -125,11 +125,13 @@
#define MLX5_FLOW_ENCAP_ACTIONS (MLX5_FLOW_ACTION_VXLAN_ENCAP | \
MLX5_FLOW_ACTION_NVGRE_ENCAP | \
- MLX5_FLOW_ACTION_RAW_ENCAP)
+ MLX5_FLOW_ACTION_RAW_ENCAP | \
+ MLX5_FLOW_ACTION_OF_PUSH_VLAN)
#define MLX5_FLOW_DECAP_ACTIONS (MLX5_FLOW_ACTION_VXLAN_DECAP | \
MLX5_FLOW_ACTION_NVGRE_DECAP | \
- MLX5_FLOW_ACTION_RAW_DECAP)
+ MLX5_FLOW_ACTION_RAW_DECAP | \
+ MLX5_FLOW_ACTION_OF_POP_VLAN)
#define MLX5_FLOW_MODIFY_HDR_ACTIONS (MLX5_FLOW_ACTION_SET_IPV4_SRC | \
MLX5_FLOW_ACTION_SET_IPV4_DST | \
@@ -140,7 +142,13 @@
MLX5_FLOW_ACTION_SET_TTL | \
MLX5_FLOW_ACTION_DEC_TTL | \
MLX5_FLOW_ACTION_SET_MAC_SRC | \
- MLX5_FLOW_ACTION_SET_MAC_DST)
+ MLX5_FLOW_ACTION_SET_MAC_DST | \
+ MLX5_FLOW_ACTION_OF_SET_VLAN_VID | \
+ MLX5_FLOW_ACTION_OF_SET_VLAN_PCP)
+
+#define MLX5_FLOW_VLAN_ACTIONS \
+ (MLX5_FLOW_ACTION_OF_POP_VLAN | MLX5_FLOW_ACTION_OF_PUSH_VLAN | \
+ MLX5_FLOW_ACTION_OF_SET_VLAN_VID | MLX5_FLOW_ACTION_OF_SET_VLAN_PCP)
#ifndef IPPROTO_MPLS
#define IPPROTO_MPLS 137
@@ -258,6 +266,16 @@ struct mlx5_flow_dv_modify_hdr_resource {
uint64_t flags; /**< Flags for RDMA API. */
};
+/* Push VLAN action resource structure */
+struct mlx5_flow_dv_push_vlan_action_resource {
+ LIST_ENTRY(mlx5_flow_dv_push_vlan_action_resource) next;
+ /* Pointer to next element. */
+ rte_atomic32_t refcnt; /**< Reference counter. */
+ void *action;
+ /**< Direct verbs action object. */
+ uint32_t vlan_hdr; /**< VLAN header value. */
+};
+
/* Jump action resource structure. */
struct mlx5_flow_dv_jump_tbl_resource {
LIST_ENTRY(mlx5_flow_dv_jump_tbl_resource) next;
@@ -297,6 +315,8 @@ struct mlx5_flow_dv {
/**< Pointer to encap/decap resource in cache. */
struct mlx5_flow_dv_modify_hdr_resource *modify_hdr;
/**< Pointer to modify header resource in cache. */
+ struct mlx5_flow_dv_push_vlan_action_resource *push_vlan_action;
+ /**< Pointer to push VLAN action resource in cache. */
struct ibv_flow *flow; /**< Installed flow. */
struct mlx5_flow_dv_jump_tbl_resource *jump;
/**< Pointer to the jump action resource. */
@@ -49,6 +49,17 @@
#define MLX5DV_DR_ACTION_FLAGS_ROOT_LEVEL 1
#endif
+union flow_dr_vlan_hdr {
+ struct vlan_hdr vhdr;
+ struct {
+ uint32_t vid:12;
+ uint32_t dei:1;
+ uint32_t pcp:3;
+ uint32_t tpid:16;
+ };
+ uint32_t tag;
+} __attribute__((__packed__));
+
union flow_dv_attr {
struct {
uint32_t valid:1;
@@ -107,6 +118,12 @@ struct field_modify_info modify_eth[] = {
{0, 0, 0},
};
+struct field_modify_info modify_vlan[] = {
+ /* TODO: Fill with correct values */
+ {4, 0, MLX5_MODI_OUT_FIRST_VID},
+ {0, 0, 0},
+};
+
struct field_modify_info modify_ipv4[] = {
{1, 8, MLX5_MODI_OUT_IPV4_TTL},
{4, 12, MLX5_MODI_OUT_SIPV4},
@@ -238,6 +255,37 @@ struct field_modify_info modify_tcp[] = {
}
/**
+ * Convert modify-header set Modify-VLAN action to DV specification or create
+ * a new VLAN push action.
+ *
+ * @param[in,out] resource
+ * Pointer to the modify-header resource.
+ * @param[in] action
+ * Pointer to action specification.
+ * @param[out] error
+ * Pointer to the error structure.
+ *
+ * @return
+ * 0 on success, a negative errno value otherwise and rte_errno is set.
+ */
+static int
+flow_dv_create_action_modify_vlan
+ (struct mlx5_flow_dv_modify_hdr_resource *res,
+ const union flow_dr_vlan_hdr *vlan,
+ const uint64_t action_flags,
+ const struct rte_flow_item *items,
+ struct rte_flow_error *error)
+{
+ (void)res;
+ (void)vlan;
+ (void)action_flags;
+ (void)items;
+ return rte_flow_error_set(error, ENOTSUP,
+ RTE_FLOW_ERROR_TYPE_ACTION, NULL,
+ "unsupported action");
+}
+
+/**
* Convert modify-header set IPv4 address action to DV specification.
*
* @param[in,out] resource
@@ -819,6 +867,68 @@ struct field_modify_info modify_tcp[] = {
}
/**
+ * Validate the push VLAN action.
+ *
+ * @param[in] action_flags
+ * Holds the actions detected until now.
+ * @param[in] action
+ * Pointer to the encap action.
+ * @param[in] attr
+ * Pointer to flow attributes
+ * @param[out] error
+ * Pointer to error structure.
+ *
+ * @return
+ * 0 on success, a negative errno value otherwise and rte_errno is set.
+ */
+static int
+flow_dv_validate_action_push_vlan(uint64_t action_flags,
+ const struct rte_flow_action *action,
+ const struct rte_flow_attr *attr,
+ struct rte_flow_error *error)
+{
+ (void)action_flags;
+ (void)action;
+ (void)attr;
+ return rte_flow_error_set(error, ENOTSUP,
+ RTE_FLOW_ERROR_TYPE_ACTION, action,
+ "unsupported action");
+}
+
+/**
+ * Validate the pop VLAN action.
+ *
+ * @param[in] action_flags
+ * Holds the actions detected until now.
+ * @param[in] action
+ * Pointer to the pop vlan action.
+ * @param[in] item_flags
+ * The items found in this flow rule.
+ * @param[in] attr
+ * Pointer to flow attributes.
+ * @param[out] error
+ * Pointer to error structure.
+ *
+ * @return
+ * 0 on success, a negative errno value otherwise and rte_errno is set.
+ */
+static int
+flow_dv_validate_action_pop_vlan(uint64_t action_flags,
+ const struct rte_flow_action *action,
+ uint64_t item_flags,
+ const struct rte_flow_attr *attr,
+ struct rte_flow_error *error)
+{
+ (void)action_flags;
+ (void)action;
+ (void)item_flags;
+ (void)attr;
+ return rte_flow_error_set(error, ENOTSUP,
+ RTE_FLOW_ERROR_TYPE_ACTION, action,
+ "unsupported action");
+}
+
+/**
* Validate the raw encap action.
*
* @param[in] action_flags
@@ -1502,6 +1612,37 @@ struct field_modify_info modify_tcp[] = {
}
/**
+ * Create action push VLAN.
+ *
+ * @param[in] dev
+ * Pointer to rte_eth_dev structure.
+ * @param[in] vlan_tag
+ * the vlan tag to push to the Ethernet header.
+ * @param[in, out] dev_flow
+ * Pointer to the mlx5_flow.
+ * @param[in] attr
+ * Pointer to the flow attributes.
+ * @param[out] error
+ * Pointer to the error structure.
+ *
+ * @return
+ * 0 on success, a negative errno value otherwise and rte_errno is set.
+ */
+static int
+flow_dv_create_action_push_vlan(struct rte_eth_dev *dev,
+ const uint32_t vlan_tag,
+ struct mlx5_flow *dev_flow,
+ struct rte_flow_error *error)
+{
+ (void)dev;
+ (void)vlan_tag;
+ (void)dev_flow;
+ return rte_flow_error_set(error, ENOTSUP,
+ RTE_FLOW_ERROR_TYPE_ACTION,
+ NULL, "unsupported action");
+}
+
+/**
* Validate the modify-header actions.
*
* @param[in] action_flags
@@ -1566,6 +1707,34 @@ struct field_modify_info modify_tcp[] = {
}
/**
+ * Validate the modify-header VLAN actions.
+ *
+ * @param[in] action_flags
+ * Holds the actions detected until now.
+ * @param[in] action
+ * Pointer to the modify action.
+ * @param[in] item_flags
+ * Holds the items detected.
+ * @param[out] error
+ * Pointer to error structure.
+ *
+ * @return
+ * 0 on success, a negative errno value otherwise and rte_errno is set.
+ */
+static int
+flow_dv_validate_action_modify_vlan(const uint64_t action_flags,
+ const struct rte_flow_action *action,
+ const uint64_t item_flags,
+ struct rte_flow_error *error)
+{
+ (void)action_flags;
+ (void)action;
+ (void)item_flags;
+ return rte_flow_error_set(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ACTION,
+ NULL, "unsupported action");
+}
+
+/**
* Validate the modify-header IPv4 address actions.
*
* @param[in] action_flags
@@ -2277,6 +2446,26 @@ struct field_modify_info modify_tcp[] = {
action_flags |= MLX5_FLOW_ACTION_COUNT;
++actions_n;
break;
+ case RTE_FLOW_ACTION_TYPE_OF_PUSH_VLAN:
+ ret = flow_dv_validate_action_push_vlan(action_flags,
+ actions, attr,
+ error);
+ if (ret < 0)
+ return ret;
+ action_flags |= MLX5_FLOW_ACTION_OF_PUSH_VLAN;
+ ++actions_n;
+ break;
+ case RTE_FLOW_ACTION_TYPE_OF_POP_VLAN:
+ ret = flow_dv_validate_action_pop_vlan(action_flags,
+ actions,
+ item_flags, attr,
+ error);
+ return -rte_errno;
+ if (ret < 0)
+ return ret;
+ action_flags |= MLX5_FLOW_ACTION_OF_POP_VLAN;
+ ++actions_n;
+ break;
case RTE_FLOW_ACTION_TYPE_VXLAN_ENCAP:
case RTE_FLOW_ACTION_TYPE_NVGRE_ENCAP:
ret = flow_dv_validate_action_l2_encap(action_flags,
@@ -2336,7 +2525,22 @@ struct field_modify_info modify_tcp[] = {
MLX5_FLOW_ACTION_SET_MAC_SRC :
MLX5_FLOW_ACTION_SET_MAC_DST;
break;
-
+ case RTE_FLOW_ACTION_TYPE_OF_SET_VLAN_VID:
+ case RTE_FLOW_ACTION_TYPE_OF_SET_VLAN_PCP:
+ ret = flow_dv_validate_action_modify_vlan(action_flags,
+ actions,
+ item_flags,
+ error);
+ if (ret < 0)
+ return ret;
+ /* Count all modify-header actions as one action. */
+ if (!(action_flags & MLX5_FLOW_MODIFY_HDR_ACTIONS))
+ ++actions_n;
+ action_flags |= actions->type ==
+ RTE_FLOW_ACTION_TYPE_OF_SET_VLAN_VID ?
+ MLX5_FLOW_ACTION_OF_SET_VLAN_VID :
+ MLX5_FLOW_ACTION_OF_SET_VLAN_PCP;
+ break;
case RTE_FLOW_ACTION_TYPE_SET_IPV4_SRC:
case RTE_FLOW_ACTION_TYPE_SET_IPV4_DST:
ret = flow_dv_validate_action_modify_ipv4(action_flags,
@@ -3634,6 +3838,7 @@ struct field_modify_info modify_tcp[] = {
uint32_t modify_action_position = UINT32_MAX;
void *match_mask = matcher.mask.buf;
void *match_value = dev_flow->dv.value.buf;
+ union flow_dr_vlan_hdr vlan;
flow->group = attr->group;
if (attr->transfer)
@@ -3740,6 +3945,37 @@ struct field_modify_info modify_tcp[] = {
action,
"cannot create counter"
" object.");
+ break;
+ case RTE_FLOW_ACTION_TYPE_OF_POP_VLAN:
+ if (!priv->sh->pop_vlan_action)
+ return rte_flow_error_set
+ (error, ENOTSUP,
+ RTE_FLOW_ERROR_TYPE_ACTION,
+ action,
+ "cannot create pop vlan"
+ " action.");
+ dev_flow->dv.actions[actions_n++] =
+ priv->sh->pop_vlan_action;
+ action_flags |= MLX5_FLOW_ACTION_OF_POP_VLAN;
+ break;
+ case RTE_FLOW_ACTION_TYPE_OF_PUSH_VLAN:
+ vlan.tpid =
+ ((const struct rte_flow_action_of_push_vlan *)
+ actions->conf)->ethertype;
+ action_flags |= MLX5_FLOW_ACTION_OF_PUSH_VLAN;
+ break;
+ case RTE_FLOW_ACTION_TYPE_OF_SET_VLAN_VID:
+ vlan.vid =
+ ((const struct rte_flow_action_of_set_vlan_vid *)
+ actions->conf)->vlan_vid;
+ action_flags |= MLX5_FLOW_ACTION_OF_SET_VLAN_VID;
+ break;
+ case RTE_FLOW_ACTION_TYPE_OF_SET_VLAN_PCP:
+ vlan.pcp =
+ ((const struct rte_flow_action_of_set_vlan_pcp *)
+ actions->conf)->vlan_pcp;
+ action_flags |= MLX5_FLOW_ACTION_OF_SET_VLAN_PCP;
+ break;
case RTE_FLOW_ACTION_TYPE_VXLAN_ENCAP:
case RTE_FLOW_ACTION_TYPE_NVGRE_ENCAP:
if (flow_dv_create_action_l2_encap(dev, actions,
@@ -3886,12 +4122,31 @@ struct field_modify_info modify_tcp[] = {
break;
case RTE_FLOW_ACTION_TYPE_END:
actions_end = true;
+ /*
+ * Finally we can handle the VLAN commands.
+ * If we have a push VLAN action it will handle all
+ * other VLAN modify-header actions.
+ */
+ if (action_flags & MLX5_FLOW_ACTION_OF_PUSH_VLAN) {
+ action_flags &=
+ ~(MLX5_FLOW_ACTION_OF_SET_VLAN_VID |
+ MLX5_FLOW_ACTION_OF_SET_VLAN_PCP);
+ if (flow_dv_create_action_push_vlan
+ (dev, vlan.tag, dev_flow, error))
+ return -rte_errno;
+ dev_flow->dv.actions[actions_n++] =
+ dev_flow->dv.push_vlan_action;
+ } else if (action_flags & MLX5_FLOW_VLAN_ACTIONS) {
+ if (flow_dv_create_action_modify_vlan
+ (&res, &vlan,
+ action_flags, items, error))
+ return -rte_errno;
+ }
if (action_flags & MLX5_FLOW_MODIFY_HDR_ACTIONS) {
/* create modify action if needed. */
if (flow_dv_modify_hdr_resource_register
- (dev, &res,
- dev_flow,
- error))
+ (dev, &res,
+ dev_flow, error))
return -rte_errno;
dev_flow->dv.actions[modify_action_position] =
dev_flow->dv.modify_hdr->verbs_action;
@@ -408,6 +408,29 @@
}
static void *
+mlx5_glue_dr_create_flow_action_push_vlan(uint32_t vlan_tag)
+{
+#ifdef HAVE_MLX5DV_DR_VLAN
+ return mlx5dv_dr_create_action_pop_vlan(vlan_tag);
+#else
+ (void)vlan_tag;
+ errno = ENOTSUP;
+ return NULL;
+#endif
+}
+
+static void *
+mlx5_glue_dr_create_flow_action_pop_vlan(void)
+{
+#ifdef HAVE_MLX5DV_DR_VLAN
+ return mlx5dv_dr_create_action_pop_vlan();
+#else
+ errno = ENOTSUP;
+ return NULL;
+#endif
+}
+
+static void *
mlx5_glue_dr_create_flow_tbl(void *domain, uint32_t level)
{
#ifdef HAVE_MLX5DV_DR
@@ -893,6 +916,10 @@
mlx5_glue_dr_create_flow_action_dest_vport,
.dr_create_flow_action_drop =
mlx5_glue_dr_create_flow_action_drop,
+ .dr_create_flow_action_push_vlan =
+ mlx5_glue_dr_create_flow_action_push_vlan,
+ .dr_create_flow_action_pop_vlan =
+ mlx5_glue_dr_create_flow_action_pop_vlan,
.dr_create_flow_tbl = mlx5_glue_dr_create_flow_tbl,
.dr_destroy_flow_tbl = mlx5_glue_dr_destroy_flow_tbl,
.dr_create_domain = mlx5_glue_dr_create_domain,
@@ -148,6 +148,8 @@ struct mlx5_glue {
void *(*dr_create_flow_action_dest_flow_tbl)(void *tbl);
void *(*dr_create_flow_action_dest_vport)(void *domain, uint32_t vport);
void *(*dr_create_flow_action_drop)();
+ void *(*dr_create_flow_action_push_vlan)(uint32_t vlan_tag);
+ void *(*dr_create_flow_action_pop_vlan)();
void *(*dr_create_flow_tbl)(void *domain, uint32_t level);
int (*dr_destroy_flow_tbl)(void *tbl);
void *(*dr_create_domain)(struct ibv_context *ctx,
@@ -310,6 +310,7 @@ enum mlx5_modification_field {
MLX5_MODI_OUT_DIPV6_31_0,
MLX5_MODI_OUT_SIPV4,
MLX5_MODI_OUT_DIPV4,
+ MLX5_MODI_OUT_FIRST_VID,
MLX5_MODI_IN_SMAC_47_16 = 0x31,
MLX5_MODI_IN_SMAC_15_0,
MLX5_MODI_IN_ETHERTYPE,