[dpdk-dev] [RFC] net/mlx5: support for flow action on VLAN header

Moti Haimovsky motih at mellanox.com
Thu May 16 17:20:35 CEST 2019


VLAN actions support is implemented in librte_ethdev, and in
test-pmd application, based on [1] Generic flow API.
These actions conform to the VLAN actions defined in
[2] the OpenFlow Switch Specification.

rte_flow defines the following VLAN actions:
 1. OF_POP_VLAN
    Pop the outer-most VLAN header from the packet.
 2. OF_PUSH_VLAN
    Push a new VLAN header onto the packet.
 3. OF_SET_VLAN_VID
    Sets the ID of the outermost VLAN tag.
 4. OF_SET_VLAN_PCP
    Sets the 3-bit priority field of the outermost VLAN tag.

As for today the mlx5 PMD does not support those VLAN actions
using its Direct Verbs interface.
This RFC proposes adding this missing support to the PMD.

Comments are welcome.

[1] https://doc.dpdk.org/guides/prog_guide/rte_flow.html

[2] https://www.opennetworking.org/wp-content/uploads/2014/10/
    openflow-spec-v1.4.0.pdf

Signed-off-by: Moti Haimovsky <motih at mellanox.com>
---
 drivers/net/mlx5/Makefile       |   2 +-
 drivers/net/mlx5/meson.build    |   2 +-
 drivers/net/mlx5/mlx5.c         |   9 ++
 drivers/net/mlx5/mlx5.h         |   1 +
 drivers/net/mlx5/mlx5_flow.h    |  26 +++-
 drivers/net/mlx5/mlx5_flow_dv.c | 263 +++++++++++++++++++++++++++++++++++++++-
 drivers/net/mlx5/mlx5_glue.c    |  27 +++++
 drivers/net/mlx5/mlx5_glue.h    |   2 +
 drivers/net/mlx5/mlx5_prm.h     |   1 +
 9 files changed, 324 insertions(+), 9 deletions(-)

diff --git a/drivers/net/mlx5/Makefile b/drivers/net/mlx5/Makefile
index 2694916..4a4225e 100644
--- a/drivers/net/mlx5/Makefile
+++ b/drivers/net/mlx5/Makefile
@@ -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
diff --git a/drivers/net/mlx5/meson.build b/drivers/net/mlx5/meson.build
index ac3b529..f1f97a1 100644
--- a/drivers/net/mlx5/meson.build
+++ b/drivers/net/mlx5/meson.build
@@ -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)
diff --git a/drivers/net/mlx5/mlx5.c b/drivers/net/mlx5/mlx5.c
index 9f5ec97..2000350 100644
--- a/drivers/net/mlx5/mlx5.c
+++ b/drivers/net/mlx5/mlx5.c
@@ -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);
diff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h
index 3eaaafd..b9e621d 100644
--- a/drivers/net/mlx5/mlx5.h
+++ b/drivers/net/mlx5/mlx5.h
@@ -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;
diff --git a/drivers/net/mlx5/mlx5_flow.h b/drivers/net/mlx5/mlx5_flow.h
index b665420..0fdba46 100644
--- a/drivers/net/mlx5/mlx5_flow.h
+++ b/drivers/net/mlx5/mlx5_flow.h
@@ -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. */
diff --git a/drivers/net/mlx5/mlx5_flow_dv.c b/drivers/net/mlx5/mlx5_flow_dv.c
index cf255ca..b8b4e58 100644
--- a/drivers/net/mlx5/mlx5_flow_dv.c
+++ b/drivers/net/mlx5/mlx5_flow_dv.c
@@ -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;
diff --git a/drivers/net/mlx5/mlx5_glue.c b/drivers/net/mlx5/mlx5_glue.c
index 21cd3bb..66bc66e 100644
--- a/drivers/net/mlx5/mlx5_glue.c
+++ b/drivers/net/mlx5/mlx5_glue.c
@@ -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,
diff --git a/drivers/net/mlx5/mlx5_glue.h b/drivers/net/mlx5/mlx5_glue.h
index b5c63cb..39bbf00 100644
--- a/drivers/net/mlx5/mlx5_glue.h
+++ b/drivers/net/mlx5/mlx5_glue.h
@@ -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,
diff --git a/drivers/net/mlx5/mlx5_prm.h b/drivers/net/mlx5/mlx5_prm.h
index 8c42380..d106aff 100644
--- a/drivers/net/mlx5/mlx5_prm.h
+++ b/drivers/net/mlx5/mlx5_prm.h
@@ -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,
-- 
1.8.3.1



More information about the dev mailing list