@@ -327,6 +327,32 @@ Run-time configuration
Enabled by default, valid only on VF devices ignored otherwise.
+- ``l3_vxlan_en`` parameter [int]
+
+ A nonzero value allows L3 VXLAN flow creation. To enable L3 VXLAN, users
+ has to configure firemware and enable this prameter. This is a prerequisite
+ to receive this kind of traffic.
+
+ Disabled by default.
+
+Firmware configuration
+~~~~~~~~~~~~~~~~~~~~~~
+
+- L3 VXLAN destination UDP port
+
+ .. code-block:: console
+
+ mlxconfig -d <mst device> set IP_OVER_VXLAN_EN=1
+ mlxconfig -d <mst device> set IP_OVER_VXLAN_PORT=<udp dport>
+
+ Verify configurations are set:
+
+ .. code-block:: console
+
+ mlxconfig -d <mst device> query | grep IP_OVER_VXLAN
+ IP_OVER_VXLAN_EN True(1)
+ IP_OVER_VXLAN_PORT <udp dport>
+
Prerequisites
-------------
@@ -69,6 +69,9 @@
/* Device parameter to enable hardware Rx vector. */
#define MLX5_RX_VEC_EN "rx_vec_en"
+/* Allow L3 VXLAN flow creation. */
+#define MLX5_L3_VXLAN_EN "l3_vxlan_en"
+
/* Activate Netlink support in VF mode. */
#define MLX5_VF_NL_EN "vf_nl_en"
@@ -416,6 +419,8 @@ mlx5_args_check(const char *key, const char *val, void *opaque)
config->tx_vec_en = !!tmp;
} else if (strcmp(MLX5_RX_VEC_EN, key) == 0) {
config->rx_vec_en = !!tmp;
+ } else if (strcmp(MLX5_L3_VXLAN_EN, key) == 0) {
+ config->l3_vxlan_en = !!tmp;
} else if (strcmp(MLX5_VF_NL_EN, key) == 0) {
config->vf_nl_en = !!tmp;
} else {
@@ -449,6 +454,7 @@ mlx5_args(struct mlx5_dev_config *config, struct rte_devargs *devargs)
MLX5_TXQ_MAX_INLINE_LEN,
MLX5_TX_VEC_EN,
MLX5_RX_VEC_EN,
+ MLX5_L3_VXLAN_EN,
MLX5_VF_NL_EN,
NULL,
};
@@ -88,6 +88,7 @@ struct mlx5_dev_config {
unsigned int tx_vec_en:1; /* Tx vector is enabled. */
unsigned int rx_vec_en:1; /* Rx vector is enabled. */
unsigned int mpw_hdr_dseg:1; /* Enable DSEGs in the title WQEBB. */
+ unsigned int l3_vxlan_en:1; /* Enable L3 VXLAN flow creation. */
unsigned int vf_nl_en:1; /* Enable Netlink requests in VF mode. */
unsigned int max_verbs_prio; /* Number of Verb flow priorities. */
unsigned int tso_max_payload_sz; /* Maximum TCP payload for TSO. */
@@ -51,6 +51,7 @@ extern const struct eth_dev_ops mlx5_dev_ops_isolate;
/** Structure give to the conversion functions. */
struct mlx5_flow_data {
+ struct rte_eth_dev *dev; /** Ethernet device. */
struct mlx5_flow_parse *parser; /** Parser context. */
struct rte_flow_error *error; /** Error context. */
};
@@ -413,7 +414,9 @@ static const struct mlx5_flow_items mlx5_flow_items[] = {
.dst_sz = sizeof(struct ibv_flow_spec_tunnel),
},
[RTE_FLOW_ITEM_TYPE_VXLAN] = {
- .items = ITEMS(RTE_FLOW_ITEM_TYPE_ETH),
+ .items = ITEMS(RTE_FLOW_ITEM_TYPE_ETH,
+ RTE_FLOW_ITEM_TYPE_IPV4, /* For L3 VXLAN. */
+ RTE_FLOW_ITEM_TYPE_IPV6), /* For L3 VXLAN. */
.actions = valid_actions,
.mask = &(const struct rte_flow_item_vxlan){
.vni = "\xff\xff\xff",
@@ -1175,6 +1178,7 @@ mlx5_flow_convert(struct rte_eth_dev *dev,
parser->inner = 0;
for (; items->type != RTE_FLOW_ITEM_TYPE_END; ++items) {
struct mlx5_flow_data data = {
+ .dev = dev,
.parser = parser,
.error = error,
};
@@ -1396,6 +1400,7 @@ mlx5_flow_create_ipv4(const struct rte_flow_item *item,
const void *default_mask,
struct mlx5_flow_data *data)
{
+ struct priv *priv = data->dev->data->dev_private;
const struct rte_flow_item_ipv4 *spec = item->spec;
const struct rte_flow_item_ipv4 *mask = item->mask;
struct mlx5_flow_parse *parser = data->parser;
@@ -1405,6 +1410,15 @@ mlx5_flow_create_ipv4(const struct rte_flow_item *item,
.size = ipv4_size,
};
+ if (parser->layer == HASH_RXQ_TUNNEL &&
+ parser->tunnel == ptype_ext[PTYPE_IDX(RTE_PTYPE_TUNNEL_VXLAN)] &&
+ !priv->config.l3_vxlan_en)
+ return rte_flow_error_set(data->error, EINVAL,
+ RTE_FLOW_ERROR_TYPE_ITEM,
+ item,
+ "L3 VXLAN not enabled by device"
+ " parameter and/or not configured"
+ " in firmware");
/* Don't update layer for the inner pattern. */
if (!parser->inner)
parser->layer = HASH_RXQ_IPV4;
@@ -1451,6 +1465,7 @@ mlx5_flow_create_ipv6(const struct rte_flow_item *item,
const void *default_mask,
struct mlx5_flow_data *data)
{
+ struct priv *priv = data->dev->data->dev_private;
const struct rte_flow_item_ipv6 *spec = item->spec;
const struct rte_flow_item_ipv6 *mask = item->mask;
struct mlx5_flow_parse *parser = data->parser;
@@ -1460,6 +1475,15 @@ mlx5_flow_create_ipv6(const struct rte_flow_item *item,
.size = ipv6_size,
};
+ if (parser->layer == HASH_RXQ_TUNNEL &&
+ parser->tunnel == ptype_ext[PTYPE_IDX(RTE_PTYPE_TUNNEL_VXLAN)] &&
+ !priv->config.l3_vxlan_en)
+ return rte_flow_error_set(data->error, EINVAL,
+ RTE_FLOW_ERROR_TYPE_ITEM,
+ item,
+ "L3 VXLAN not enabled by device"
+ " parameter and/or not configured"
+ " in firmware");
/* Don't update layer for the inner pattern. */
if (!parser->inner)
parser->layer = HASH_RXQ_IPV6;