* [dpdk-dev] [PATCH v6 1/4] ethdev: add MPLS and GRE items
2017-03-30 8:29 [dpdk-dev] [PATCH v6 0/4] add support for MPLS tunnel filter Beilei Xing
@ 2017-03-30 8:29 ` Beilei Xing
2017-03-30 8:29 ` [dpdk-dev] [PATCH v6 2/4] app/testpmd: add MPLS and GRE fields to flow command Beilei Xing
` (3 subsequent siblings)
4 siblings, 0 replies; 6+ messages in thread
From: Beilei Xing @ 2017-03-30 8:29 UTC (permalink / raw)
To: jingjing.wu; +Cc: helin.zhang, bernard.iremonger, dev, beilei.xing
This patch adds MPLS and GRE items to generic rte flow.
Signed-off-by: Beilei Xing <beilei.xing@intel.com>
Acked-by: Adrien Mazarguil <adrien.mazarguil@6wind.com>
---
doc/guides/prog_guide/rte_flow.rst | 21 ++++++++++++++--
lib/librte_ether/rte_flow.h | 51 ++++++++++++++++++++++++++++++++++++++
2 files changed, 70 insertions(+), 2 deletions(-)
diff --git a/doc/guides/prog_guide/rte_flow.rst b/doc/guides/prog_guide/rte_flow.rst
index 3bf8871..5ee045e 100644
--- a/doc/guides/prog_guide/rte_flow.rst
+++ b/doc/guides/prog_guide/rte_flow.rst
@@ -187,8 +187,8 @@ Pattern item
Pattern items fall in two categories:
- Matching protocol headers and packet data (ANY, RAW, ETH, VLAN, IPV4,
- IPV6, ICMP, UDP, TCP, SCTP, VXLAN and so on), usually associated with a
- specification structure.
+ IPV6, ICMP, UDP, TCP, SCTP, VXLAN, MPLS, GRE and so on), usually
+ associated with a specification structure.
- Matching meta-data or affecting pattern processing (END, VOID, INVERT, PF,
VF, PORT and so on), often without a specification structure.
@@ -863,6 +863,23 @@ Matches a VXLAN header (RFC 7348).
- ``rsvd1``: reserved, normally 0x00.
- Default ``mask`` matches VNI only.
+Item: ``MPLS``
+^^^^^^^^^^^^^^
+
+Matches a MPLS header.
+
+- ``label_tc_s_ttl``: label, TC, Bottom of Stack and TTL.
+- Default ``mask`` matches label only.
+
+Item: ``GRE``
+^^^^^^^^^^^^^^
+
+Matches a GRE header.
+
+- ``c_rsvd0_ver``: checksum, reserved 0 and version.
+- ``protocol``: protocol type.
+- Default ``mask`` matches protocol only.
+
Actions
~~~~~~~
diff --git a/lib/librte_ether/rte_flow.h b/lib/librte_ether/rte_flow.h
index 171a569..8013eca 100644
--- a/lib/librte_ether/rte_flow.h
+++ b/lib/librte_ether/rte_flow.h
@@ -282,6 +282,20 @@ enum rte_flow_item_type {
* See struct rte_flow_item_nvgre.
*/
RTE_FLOW_ITEM_TYPE_NVGRE,
+
+ /**
+ * Matches a MPLS header.
+ *
+ * See struct rte_flow_item_mpls.
+ */
+ RTE_FLOW_ITEM_TYPE_MPLS,
+
+ /**
+ * Matches a GRE header.
+ *
+ * See struct rte_flow_item_gre.
+ */
+ RTE_FLOW_ITEM_TYPE_GRE,
};
/**
@@ -599,6 +613,43 @@ struct rte_flow_item_nvgre {
};
/**
+ * RTE_FLOW_ITEM_TYPE_MPLS.
+ *
+ * Matches a MPLS header.
+ */
+struct rte_flow_item_mpls {
+ /**
+ * Label (20b), TC (3b), Bottom of Stack (1b).
+ */
+ uint8_t label_tc_s[3];
+ uint8_t ttl; /** Time-to-Live. */
+};
+
+/** Default mask for RTE_FLOW_ITEM_TYPE_MPLS. */
+static const struct rte_flow_item_mpls rte_flow_item_mpls_mask = {
+ .label_tc_s = "\xff\xff\xf0",
+};
+
+/**
+ * RTE_FLOW_ITEM_TYPE_GRE.
+ *
+ * Matches a GRE header.
+ */
+struct rte_flow_item_gre {
+ /**
+ * Checksum (1b), reserved 0 (12b), version (3b).
+ * Refer to RFC 2784.
+ */
+ uint16_t c_rsvd0_ver;
+ uint16_t protocol; /**< Protocol type. */
+};
+
+/** Default mask for RTE_FLOW_ITEM_TYPE_GRE. */
+static const struct rte_flow_item_gre rte_flow_item_gre_mask = {
+ .protocol = 0xffff,
+};
+
+/**
* Matching pattern item definition.
*
* A pattern is formed by stacking items starting from the lowest protocol
--
2.5.5
^ permalink raw reply [flat|nested] 6+ messages in thread
* [dpdk-dev] [PATCH v6 2/4] app/testpmd: add MPLS and GRE fields to flow command
2017-03-30 8:29 [dpdk-dev] [PATCH v6 0/4] add support for MPLS tunnel filter Beilei Xing
2017-03-30 8:29 ` [dpdk-dev] [PATCH v6 1/4] ethdev: add MPLS and GRE items Beilei Xing
@ 2017-03-30 8:29 ` Beilei Xing
2017-03-30 8:29 ` [dpdk-dev] [PATCH v6 3/4] net/i40e: add MPLS parsing function Beilei Xing
` (2 subsequent siblings)
4 siblings, 0 replies; 6+ messages in thread
From: Beilei Xing @ 2017-03-30 8:29 UTC (permalink / raw)
To: jingjing.wu; +Cc: helin.zhang, bernard.iremonger, dev, beilei.xing
This patch exposes the following item fields through the flow command:
- MPLS label
- GRE protocol
Signed-off-by: Beilei Xing <beilei.xing@intel.com>
Acked-by: Adrien Mazarguil <adrien.mazarguil@6wind.com>
---
app/test-pmd/cmdline_flow.c | 47 +++++++++++++++++++++++++++++
app/test-pmd/config.c | 2 ++
doc/guides/testpmd_app_ug/testpmd_funcs.rst | 8 +++++
3 files changed, 57 insertions(+)
diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
index ff98690..2149df4 100644
--- a/app/test-pmd/cmdline_flow.c
+++ b/app/test-pmd/cmdline_flow.c
@@ -159,6 +159,10 @@ enum index {
ITEM_SCTP_CKSUM,
ITEM_VXLAN,
ITEM_VXLAN_VNI,
+ ITEM_MPLS,
+ ITEM_MPLS_LABEL,
+ ITEM_GRE,
+ ITEM_GRE_PROTO,
/* Validate/create actions. */
ACTIONS,
@@ -432,6 +436,8 @@ static const enum index next_item[] = {
ITEM_TCP,
ITEM_SCTP,
ITEM_VXLAN,
+ ITEM_MPLS,
+ ITEM_GRE,
ZERO,
};
@@ -538,6 +544,18 @@ static const enum index item_vxlan[] = {
ZERO,
};
+static const enum index item_mpls[] = {
+ ITEM_MPLS_LABEL,
+ ITEM_NEXT,
+ ZERO,
+};
+
+static const enum index item_gre[] = {
+ ITEM_GRE_PROTO,
+ ITEM_NEXT,
+ ZERO,
+};
+
static const enum index next_action[] = {
ACTION_END,
ACTION_VOID,
@@ -1279,6 +1297,35 @@ static const struct token token_list[] = {
.next = NEXT(item_vxlan, NEXT_ENTRY(UNSIGNED), item_param),
.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vxlan, vni)),
},
+ [ITEM_MPLS] = {
+ .name = "mpls",
+ .help = "match MPLS header",
+ .priv = PRIV_ITEM(MPLS, sizeof(struct rte_flow_item_mpls)),
+ .next = NEXT(item_mpls),
+ .call = parse_vc,
+ },
+ [ITEM_MPLS_LABEL] = {
+ .name = "label",
+ .help = "MPLS label",
+ .next = NEXT(item_mpls, NEXT_ENTRY(UNSIGNED), item_param),
+ .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_mpls,
+ label_tc_s,
+ "\xff\xff\xf0")),
+ },
+ [ITEM_GRE] = {
+ .name = "gre",
+ .help = "match GRE header",
+ .priv = PRIV_ITEM(GRE, sizeof(struct rte_flow_item_gre)),
+ .next = NEXT(item_gre),
+ .call = parse_vc,
+ },
+ [ITEM_GRE_PROTO] = {
+ .name = "protocol",
+ .help = "GRE protocol type",
+ .next = NEXT(item_gre, NEXT_ENTRY(UNSIGNED), item_param),
+ .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_gre,
+ protocol)),
+ },
/* Validate/create actions. */
[ACTIONS] = {
.name = "actions",
diff --git a/app/test-pmd/config.c b/app/test-pmd/config.c
index 9865bf1..780ce6b 100644
--- a/app/test-pmd/config.c
+++ b/app/test-pmd/config.c
@@ -963,6 +963,8 @@ static const struct {
MK_FLOW_ITEM(TCP, sizeof(struct rte_flow_item_tcp)),
MK_FLOW_ITEM(SCTP, sizeof(struct rte_flow_item_sctp)),
MK_FLOW_ITEM(VXLAN, sizeof(struct rte_flow_item_vxlan)),
+ MK_FLOW_ITEM(MPLS, sizeof(struct rte_flow_item_mpls)),
+ MK_FLOW_ITEM(GRE, sizeof(struct rte_flow_item_gre)),
};
/** Compute storage space needed by item specification. */
diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
index f08a795..62478d6 100644
--- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
+++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
@@ -2481,6 +2481,14 @@ This section lists supported pattern items and their attributes, if any.
- ``vni {unsigned}``: VXLAN identifier.
+- ``mpls``: match MPLS header.
+
+ - ``label {unsigned}``: MPLS label.
+
+- ``gre``: match GRE header.
+
+ - ``protocol {unsigned}``: protocol type.
+
Actions list
^^^^^^^^^^^^
--
2.5.5
^ permalink raw reply [flat|nested] 6+ messages in thread
* [dpdk-dev] [PATCH v6 3/4] net/i40e: add MPLS parsing function
2017-03-30 8:29 [dpdk-dev] [PATCH v6 0/4] add support for MPLS tunnel filter Beilei Xing
2017-03-30 8:29 ` [dpdk-dev] [PATCH v6 1/4] ethdev: add MPLS and GRE items Beilei Xing
2017-03-30 8:29 ` [dpdk-dev] [PATCH v6 2/4] app/testpmd: add MPLS and GRE fields to flow command Beilei Xing
@ 2017-03-30 8:29 ` Beilei Xing
2017-03-30 8:29 ` [dpdk-dev] [PATCH v6 4/4] net/i40e: enable tunnel filter for MPLS Beilei Xing
2017-03-30 17:04 ` [dpdk-dev] [PATCH v6 0/4] add support for MPLS tunnel filter Ferruh Yigit
4 siblings, 0 replies; 6+ messages in thread
From: Beilei Xing @ 2017-03-30 8:29 UTC (permalink / raw)
To: jingjing.wu; +Cc: helin.zhang, bernard.iremonger, dev, beilei.xing
This patch add MPLS parsing function to support
MPLS filtering.
Signed-off-by: Beilei Xing <beilei.xing@intel.com>
Acked-by: Jingjing Wu <jingjing.wu@intel.com>
---
drivers/net/i40e/i40e_ethdev.h | 2 +
drivers/net/i40e/i40e_flow.c | 205 ++++++++++++++++++++++++++++++++++++++++-
2 files changed, 206 insertions(+), 1 deletion(-)
diff --git a/drivers/net/i40e/i40e_ethdev.h b/drivers/net/i40e/i40e_ethdev.h
index 9aacff7..dec1bd6 100644
--- a/drivers/net/i40e/i40e_ethdev.h
+++ b/drivers/net/i40e/i40e_ethdev.h
@@ -543,6 +543,8 @@ enum i40e_tunnel_type {
I40E_TUNNEL_TYPE_NVGRE,
I40E_TUNNEL_TYPE_IP_IN_GRE,
I40E_L2_TUNNEL_TYPE_E_TAG,
+ I40E_TUNNEL_TYPE_MPLSoUDP,
+ I40E_TUNNEL_TYPE_MPLSoGRE,
I40E_TUNNEL_TYPE_MAX,
};
diff --git a/drivers/net/i40e/i40e_flow.c b/drivers/net/i40e/i40e_flow.c
index 148e519..d5c705e 100644
--- a/drivers/net/i40e/i40e_flow.c
+++ b/drivers/net/i40e/i40e_flow.c
@@ -114,6 +114,12 @@ static int i40e_flow_parse_vxlan_filter(struct rte_eth_dev *dev,
const struct rte_flow_action actions[],
struct rte_flow_error *error,
union i40e_filter_t *filter);
+static int i40e_flow_parse_mpls_filter(struct rte_eth_dev *dev,
+ const struct rte_flow_attr *attr,
+ const struct rte_flow_item pattern[],
+ const struct rte_flow_action actions[],
+ struct rte_flow_error *error,
+ union i40e_filter_t *filter);
static int i40e_flow_destroy_ethertype_filter(struct i40e_pf *pf,
struct i40e_ethertype_filter *filter);
static int i40e_flow_destroy_tunnel_filter(struct i40e_pf *pf,
@@ -278,6 +284,39 @@ static enum rte_flow_item_type pattern_vxlan_4[] = {
RTE_FLOW_ITEM_TYPE_END,
};
+/* Pattern matched MPLS */
+static enum rte_flow_item_type pattern_mpls_1[] = {
+ RTE_FLOW_ITEM_TYPE_ETH,
+ RTE_FLOW_ITEM_TYPE_IPV4,
+ RTE_FLOW_ITEM_TYPE_UDP,
+ RTE_FLOW_ITEM_TYPE_MPLS,
+ RTE_FLOW_ITEM_TYPE_END,
+};
+
+static enum rte_flow_item_type pattern_mpls_2[] = {
+ RTE_FLOW_ITEM_TYPE_ETH,
+ RTE_FLOW_ITEM_TYPE_IPV6,
+ RTE_FLOW_ITEM_TYPE_UDP,
+ RTE_FLOW_ITEM_TYPE_MPLS,
+ RTE_FLOW_ITEM_TYPE_END,
+};
+
+static enum rte_flow_item_type pattern_mpls_3[] = {
+ RTE_FLOW_ITEM_TYPE_ETH,
+ RTE_FLOW_ITEM_TYPE_IPV4,
+ RTE_FLOW_ITEM_TYPE_GRE,
+ RTE_FLOW_ITEM_TYPE_MPLS,
+ RTE_FLOW_ITEM_TYPE_END,
+};
+
+static enum rte_flow_item_type pattern_mpls_4[] = {
+ RTE_FLOW_ITEM_TYPE_ETH,
+ RTE_FLOW_ITEM_TYPE_IPV6,
+ RTE_FLOW_ITEM_TYPE_GRE,
+ RTE_FLOW_ITEM_TYPE_MPLS,
+ RTE_FLOW_ITEM_TYPE_END,
+};
+
static struct i40e_valid_pattern i40e_supported_patterns[] = {
/* Ethertype */
{ pattern_ethertype, i40e_flow_parse_ethertype_filter },
@@ -303,6 +342,11 @@ static struct i40e_valid_pattern i40e_supported_patterns[] = {
{ pattern_vxlan_2, i40e_flow_parse_vxlan_filter },
{ pattern_vxlan_3, i40e_flow_parse_vxlan_filter },
{ pattern_vxlan_4, i40e_flow_parse_vxlan_filter },
+ /* MPLSoUDP & MPLSoGRE */
+ { pattern_mpls_1, i40e_flow_parse_mpls_filter },
+ { pattern_mpls_2, i40e_flow_parse_mpls_filter },
+ { pattern_mpls_3, i40e_flow_parse_mpls_filter },
+ { pattern_mpls_4, i40e_flow_parse_mpls_filter },
};
#define NEXT_ITEM_OF_ACTION(act, actions, index) \
@@ -1515,6 +1559,165 @@ i40e_flow_parse_vxlan_filter(struct rte_eth_dev *dev,
return ret;
}
+/* 1. Last in item should be NULL as range is not supported.
+ * 2. Supported filter types: MPLS label.
+ * 3. Mask of fields which need to be matched should be
+ * filled with 1.
+ * 4. Mask of fields which needn't to be matched should be
+ * filled with 0.
+ */
+static int
+i40e_flow_parse_mpls_pattern(__rte_unused struct rte_eth_dev *dev,
+ const struct rte_flow_item *pattern,
+ struct rte_flow_error *error,
+ struct i40e_tunnel_filter_conf *filter)
+{
+ const struct rte_flow_item *item = pattern;
+ const struct rte_flow_item_mpls *mpls_spec;
+ const struct rte_flow_item_mpls *mpls_mask;
+ enum rte_flow_item_type item_type;
+ bool is_mplsoudp = 0; /* 1 - MPLSoUDP, 0 - MPLSoGRE */
+ const uint8_t label_mask[3] = {0xFF, 0xFF, 0xF0};
+ uint32_t label_be = 0;
+
+ for (; item->type != RTE_FLOW_ITEM_TYPE_END; item++) {
+ if (item->last) {
+ rte_flow_error_set(error, EINVAL,
+ RTE_FLOW_ERROR_TYPE_ITEM,
+ item,
+ "Not support range");
+ return -rte_errno;
+ }
+ item_type = item->type;
+ switch (item_type) {
+ case RTE_FLOW_ITEM_TYPE_ETH:
+ if (item->spec || item->mask) {
+ rte_flow_error_set(error, EINVAL,
+ RTE_FLOW_ERROR_TYPE_ITEM,
+ item,
+ "Invalid ETH item");
+ return -rte_errno;
+ }
+ break;
+ case RTE_FLOW_ITEM_TYPE_IPV4:
+ filter->ip_type = I40E_TUNNEL_IPTYPE_IPV4;
+ /* IPv4 is used to describe protocol,
+ * spec and mask should be NULL.
+ */
+ if (item->spec || item->mask) {
+ rte_flow_error_set(error, EINVAL,
+ RTE_FLOW_ERROR_TYPE_ITEM,
+ item,
+ "Invalid IPv4 item");
+ return -rte_errno;
+ }
+ break;
+ case RTE_FLOW_ITEM_TYPE_IPV6:
+ filter->ip_type = I40E_TUNNEL_IPTYPE_IPV6;
+ /* IPv6 is used to describe protocol,
+ * spec and mask should be NULL.
+ */
+ if (item->spec || item->mask) {
+ rte_flow_error_set(error, EINVAL,
+ RTE_FLOW_ERROR_TYPE_ITEM,
+ item,
+ "Invalid IPv6 item");
+ return -rte_errno;
+ }
+ break;
+ case RTE_FLOW_ITEM_TYPE_UDP:
+ /* UDP is used to describe protocol,
+ * spec and mask should be NULL.
+ */
+ if (item->spec || item->mask) {
+ rte_flow_error_set(error, EINVAL,
+ RTE_FLOW_ERROR_TYPE_ITEM,
+ item,
+ "Invalid UDP item");
+ return -rte_errno;
+ }
+ is_mplsoudp = 1;
+ break;
+ case RTE_FLOW_ITEM_TYPE_GRE:
+ /* GRE is used to describe protocol,
+ * spec and mask should be NULL.
+ */
+ if (item->spec || item->mask) {
+ rte_flow_error_set(error, EINVAL,
+ RTE_FLOW_ERROR_TYPE_ITEM,
+ item,
+ "Invalid GRE item");
+ return -rte_errno;
+ }
+ break;
+ case RTE_FLOW_ITEM_TYPE_MPLS:
+ mpls_spec =
+ (const struct rte_flow_item_mpls *)item->spec;
+ mpls_mask =
+ (const struct rte_flow_item_mpls *)item->mask;
+
+ if (!mpls_spec || !mpls_mask) {
+ rte_flow_error_set(error, EINVAL,
+ RTE_FLOW_ERROR_TYPE_ITEM,
+ item,
+ "Invalid MPLS item");
+ return -rte_errno;
+ }
+
+ if (memcmp(mpls_mask->label_tc_s, label_mask, 3)) {
+ rte_flow_error_set(error, EINVAL,
+ RTE_FLOW_ERROR_TYPE_ITEM,
+ item,
+ "Invalid MPLS label mask");
+ return -rte_errno;
+ }
+ rte_memcpy(((uint8_t *)&label_be + 1),
+ mpls_spec->label_tc_s, 3);
+ filter->tenant_id = rte_be_to_cpu_32(label_be) >> 4;
+ break;
+ default:
+ break;
+ }
+ }
+
+ if (is_mplsoudp)
+ filter->tunnel_type = I40E_TUNNEL_TYPE_MPLSoUDP;
+ else
+ filter->tunnel_type = I40E_TUNNEL_TYPE_MPLSoGRE;
+
+ return 0;
+}
+
+static int
+i40e_flow_parse_mpls_filter(struct rte_eth_dev *dev,
+ const struct rte_flow_attr *attr,
+ const struct rte_flow_item pattern[],
+ const struct rte_flow_action actions[],
+ struct rte_flow_error *error,
+ union i40e_filter_t *filter)
+{
+ struct i40e_tunnel_filter_conf *tunnel_filter =
+ &filter->consistent_tunnel_filter;
+ int ret;
+
+ ret = i40e_flow_parse_mpls_pattern(dev, pattern,
+ error, tunnel_filter);
+ if (ret)
+ return ret;
+
+ ret = i40e_flow_parse_tunnel_action(dev, actions, error, tunnel_filter);
+ if (ret)
+ return ret;
+
+ ret = i40e_flow_parse_attr(attr, error);
+ if (ret)
+ return ret;
+
+ cons_filter_type = RTE_ETH_FILTER_TUNNEL;
+
+ return ret;
+}
+
static int
i40e_flow_validate(struct rte_eth_dev *dev,
const struct rte_flow_attr *attr,
@@ -1750,7 +1953,7 @@ i40e_flow_destroy_tunnel_filter(struct i40e_pf *pf,
ret = i40e_aq_remove_cloud_filters(hw, vsi->seid,
&cld_filter.element, 1);
if (ret < 0)
- return ret;
+ return -ENOTSUP;
node = i40e_sw_tunnel_filter_lookup(tunnel_rule, &filter->input);
if (!node)
--
2.5.5
^ permalink raw reply [flat|nested] 6+ messages in thread
* [dpdk-dev] [PATCH v6 4/4] net/i40e: enable tunnel filter for MPLS
2017-03-30 8:29 [dpdk-dev] [PATCH v6 0/4] add support for MPLS tunnel filter Beilei Xing
` (2 preceding siblings ...)
2017-03-30 8:29 ` [dpdk-dev] [PATCH v6 3/4] net/i40e: add MPLS parsing function Beilei Xing
@ 2017-03-30 8:29 ` Beilei Xing
2017-03-30 17:04 ` [dpdk-dev] [PATCH v6 0/4] add support for MPLS tunnel filter Ferruh Yigit
4 siblings, 0 replies; 6+ messages in thread
From: Beilei Xing @ 2017-03-30 8:29 UTC (permalink / raw)
To: jingjing.wu; +Cc: helin.zhang, bernard.iremonger, dev, beilei.xing
MPLSoUDP & MPLSoGRE is not supported by tunnel
filter due to limited resource of HW, this patch
enables MPLS tunnel filter by replacing inner_mac
filter.
This configuration will be set when adding MPLSoUDP
and MPLSoGRE filter rules, and it will be invalid
only by NIC core reset.
Signed-off-by: Beilei Xing <beilei.xing@intel.com>
Acked-by: Jingjing Wu <jingjing.wu@intel.com>
---
drivers/net/i40e/i40e_ethdev.c | 190 +++++++++++++++++++++++++++++++++++++++--
drivers/net/i40e/i40e_ethdev.h | 9 ++
drivers/net/i40e/i40e_flow.c | 15 +++-
3 files changed, 203 insertions(+), 11 deletions(-)
diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 60926f0..c5167f3 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -6935,6 +6935,115 @@ i40e_dev_tunnel_filter_set(struct i40e_pf *pf,
return ret;
}
+#define I40E_AQC_REPLACE_CLOUD_CMD_INPUT_TR_WORD0 0x48
+#define I40E_TR_VXLAN_GRE_KEY_MASK 0x4
+#define I40E_TR_GENEVE_KEY_MASK 0x8
+#define I40E_TR_GENERIC_UDP_TUNNEL_MASK 0x40
+#define I40E_TR_GRE_KEY_MASK 0x400
+#define I40E_TR_GRE_KEY_WITH_XSUM_MASK 0x800
+#define I40E_TR_GRE_NO_KEY_MASK 0x8000
+
+static enum
+i40e_status_code i40e_replace_mpls_l1_filter(struct i40e_pf *pf)
+{
+ struct i40e_aqc_replace_cloud_filters_cmd filter_replace;
+ struct i40e_aqc_replace_cloud_filters_cmd_buf filter_replace_buf;
+ struct i40e_hw *hw = I40E_PF_TO_HW(pf);
+ enum i40e_status_code status = I40E_SUCCESS;
+
+ memset(&filter_replace, 0,
+ sizeof(struct i40e_aqc_replace_cloud_filters_cmd));
+ memset(&filter_replace_buf, 0,
+ sizeof(struct i40e_aqc_replace_cloud_filters_cmd_buf));
+
+ /* create L1 filter */
+ filter_replace.old_filter_type =
+ I40E_AQC_REPLACE_CLOUD_CMD_INPUT_FV_IMAC;
+ filter_replace.new_filter_type = I40E_AQC_ADD_L1_FILTER_TEID_MPLS;
+ filter_replace.tr_bit = 0;
+
+ /* Prepare the buffer, 3 entries */
+ filter_replace_buf.data[0] =
+ I40E_AQC_REPLACE_CLOUD_CMD_INPUT_FV_TEID_WORD0;
+ filter_replace_buf.data[0] |=
+ I40E_AQC_REPLACE_CLOUD_CMD_INPUT_VALIDATED;
+ filter_replace_buf.data[2] = 0xFF;
+ filter_replace_buf.data[3] = 0xFF;
+ filter_replace_buf.data[4] =
+ I40E_AQC_REPLACE_CLOUD_CMD_INPUT_FV_TEID_WORD1;
+ filter_replace_buf.data[4] |=
+ I40E_AQC_REPLACE_CLOUD_CMD_INPUT_VALIDATED;
+ filter_replace_buf.data[7] = 0xF0;
+ filter_replace_buf.data[8]
+ = I40E_AQC_REPLACE_CLOUD_CMD_INPUT_TR_WORD0;
+ filter_replace_buf.data[8] |=
+ I40E_AQC_REPLACE_CLOUD_CMD_INPUT_VALIDATED;
+ filter_replace_buf.data[10] = I40E_TR_VXLAN_GRE_KEY_MASK |
+ I40E_TR_GENEVE_KEY_MASK |
+ I40E_TR_GENERIC_UDP_TUNNEL_MASK;
+ filter_replace_buf.data[11] = (I40E_TR_GRE_KEY_MASK |
+ I40E_TR_GRE_KEY_WITH_XSUM_MASK |
+ I40E_TR_GRE_NO_KEY_MASK) >> 8;
+
+ status = i40e_aq_replace_cloud_filters(hw, &filter_replace,
+ &filter_replace_buf);
+ return status;
+}
+
+static enum
+i40e_status_code i40e_replace_mpls_cloud_filter(struct i40e_pf *pf)
+{
+ struct i40e_aqc_replace_cloud_filters_cmd filter_replace;
+ struct i40e_aqc_replace_cloud_filters_cmd_buf filter_replace_buf;
+ struct i40e_hw *hw = I40E_PF_TO_HW(pf);
+ enum i40e_status_code status = I40E_SUCCESS;
+
+ /* For MPLSoUDP */
+ memset(&filter_replace, 0,
+ sizeof(struct i40e_aqc_replace_cloud_filters_cmd));
+ memset(&filter_replace_buf, 0,
+ sizeof(struct i40e_aqc_replace_cloud_filters_cmd_buf));
+ filter_replace.valid_flags = I40E_AQC_REPLACE_CLOUD_FILTER |
+ I40E_AQC_MIRROR_CLOUD_FILTER;
+ filter_replace.old_filter_type = I40E_AQC_ADD_CLOUD_FILTER_IIP;
+ filter_replace.new_filter_type =
+ I40E_AQC_ADD_CLOUD_FILTER_TEID_MPLSoUDP;
+ /* Prepare the buffer, 2 entries */
+ filter_replace_buf.data[0] = I40E_AQC_REPLACE_CLOUD_CMD_INPUT_FV_STAG;
+ filter_replace_buf.data[0] |=
+ I40E_AQC_REPLACE_CLOUD_CMD_INPUT_VALIDATED;
+ filter_replace_buf.data[4] = I40E_AQC_ADD_L1_FILTER_TEID_MPLS;
+ filter_replace_buf.data[4] |=
+ I40E_AQC_REPLACE_CLOUD_CMD_INPUT_VALIDATED;
+ status = i40e_aq_replace_cloud_filters(hw, &filter_replace,
+ &filter_replace_buf);
+ if (status < 0)
+ return status;
+
+ /* For MPLSoGRE */
+ memset(&filter_replace, 0,
+ sizeof(struct i40e_aqc_replace_cloud_filters_cmd));
+ memset(&filter_replace_buf, 0,
+ sizeof(struct i40e_aqc_replace_cloud_filters_cmd_buf));
+
+ filter_replace.valid_flags = I40E_AQC_REPLACE_CLOUD_FILTER |
+ I40E_AQC_MIRROR_CLOUD_FILTER;
+ filter_replace.old_filter_type = I40E_AQC_ADD_CLOUD_FILTER_IMAC;
+ filter_replace.new_filter_type =
+ I40E_AQC_ADD_CLOUD_FILTER_TEID_MPLSoGRE;
+ /* Prepare the buffer, 2 entries */
+ filter_replace_buf.data[0] = I40E_AQC_REPLACE_CLOUD_CMD_INPUT_FV_STAG;
+ filter_replace_buf.data[0] |=
+ I40E_AQC_REPLACE_CLOUD_CMD_INPUT_VALIDATED;
+ filter_replace_buf.data[4] = I40E_AQC_ADD_L1_FILTER_TEID_MPLS;
+ filter_replace_buf.data[4] |=
+ I40E_AQC_REPLACE_CLOUD_CMD_INPUT_VALIDATED;
+
+ status = i40e_aq_replace_cloud_filters(hw, &filter_replace,
+ &filter_replace_buf);
+ return status;
+}
+
int
i40e_dev_consistent_tunnel_filter_set(struct i40e_pf *pf,
struct i40e_tunnel_filter_conf *tunnel_filter,
@@ -6954,6 +7063,8 @@ i40e_dev_consistent_tunnel_filter_set(struct i40e_pf *pf,
struct i40e_tunnel_rule *tunnel_rule = &pf->tunnel;
struct i40e_tunnel_filter *tunnel, *node;
struct i40e_tunnel_filter check_filter; /* Check if filter exists */
+ uint32_t teid_le;
+ bool big_buffer = 0;
cld_filter = rte_zmalloc("tunnel_filter",
sizeof(struct i40e_aqc_add_rm_cloud_filt_elem_ext),
@@ -7001,6 +7112,38 @@ i40e_dev_consistent_tunnel_filter_set(struct i40e_pf *pf,
case I40E_TUNNEL_TYPE_IP_IN_GRE:
tun_type = I40E_AQC_ADD_CLOUD_TNL_TYPE_IP;
break;
+ case I40E_TUNNEL_TYPE_MPLSoUDP:
+ if (!pf->mpls_replace_flag) {
+ i40e_replace_mpls_l1_filter(pf);
+ i40e_replace_mpls_cloud_filter(pf);
+ pf->mpls_replace_flag = 1;
+ }
+ teid_le = rte_cpu_to_le_32(tunnel_filter->tenant_id);
+ pfilter->general_fields[I40E_AQC_ADD_CLOUD_FV_FLU_0X11_WORD0] =
+ teid_le >> 4;
+ pfilter->general_fields[I40E_AQC_ADD_CLOUD_FV_FLU_0X11_WORD1] =
+ (teid_le & 0xF) << 12;
+ pfilter->general_fields[I40E_AQC_ADD_CLOUD_FV_FLU_0X11_WORD2] =
+ 0x40;
+ big_buffer = 1;
+ tun_type = I40E_AQC_ADD_CLOUD_TNL_TYPE_MPLSoUDP;
+ break;
+ case I40E_TUNNEL_TYPE_MPLSoGRE:
+ if (!pf->mpls_replace_flag) {
+ i40e_replace_mpls_l1_filter(pf);
+ i40e_replace_mpls_cloud_filter(pf);
+ pf->mpls_replace_flag = 1;
+ }
+ teid_le = rte_cpu_to_le_32(tunnel_filter->tenant_id);
+ pfilter->general_fields[I40E_AQC_ADD_CLOUD_FV_FLU_0X11_WORD0] =
+ teid_le >> 4;
+ pfilter->general_fields[I40E_AQC_ADD_CLOUD_FV_FLU_0X11_WORD1] =
+ (teid_le & 0xF) << 12;
+ pfilter->general_fields[I40E_AQC_ADD_CLOUD_FV_FLU_0X11_WORD2] =
+ 0x0;
+ big_buffer = 1;
+ tun_type = I40E_AQC_ADD_CLOUD_TNL_TYPE_MPLSoGRE;
+ break;
default:
/* Other tunnel types is not supported. */
PMD_DRV_LOG(ERR, "tunnel type is not supported.");
@@ -7008,11 +7151,19 @@ i40e_dev_consistent_tunnel_filter_set(struct i40e_pf *pf,
return -EINVAL;
}
- val = i40e_dev_get_filter_type(tunnel_filter->filter_type,
- &pfilter->element.flags);
- if (val < 0) {
- rte_free(cld_filter);
- return -EINVAL;
+ if (tunnel_filter->tunnel_type == I40E_TUNNEL_TYPE_MPLSoUDP)
+ pfilter->element.flags =
+ I40E_AQC_ADD_CLOUD_FILTER_TEID_MPLSoUDP;
+ else if (tunnel_filter->tunnel_type == I40E_TUNNEL_TYPE_MPLSoGRE)
+ pfilter->element.flags =
+ I40E_AQC_ADD_CLOUD_FILTER_TEID_MPLSoGRE;
+ else {
+ val = i40e_dev_get_filter_type(tunnel_filter->filter_type,
+ &pfilter->element.flags);
+ if (val < 0) {
+ rte_free(cld_filter);
+ return -EINVAL;
+ }
}
pfilter->element.flags |= rte_cpu_to_le_16(
@@ -7048,7 +7199,11 @@ i40e_dev_consistent_tunnel_filter_set(struct i40e_pf *pf,
}
if (add) {
- ret = i40e_aq_add_cloud_filters(hw,
+ if (big_buffer)
+ ret = i40e_aq_add_cloud_filters_big_buffer(hw,
+ vsi->seid, cld_filter, 1);
+ else
+ ret = i40e_aq_add_cloud_filters(hw,
vsi->seid, &cld_filter->element, 1);
if (ret < 0) {
PMD_DRV_LOG(ERR, "Failed to add a tunnel filter.");
@@ -7058,7 +7213,11 @@ i40e_dev_consistent_tunnel_filter_set(struct i40e_pf *pf,
rte_memcpy(tunnel, &check_filter, sizeof(check_filter));
ret = i40e_sw_tunnel_filter_insert(pf, tunnel);
} else {
- ret = i40e_aq_remove_cloud_filters(hw, vsi->seid,
+ if (big_buffer)
+ ret = i40e_aq_remove_cloud_filters_big_buffer(
+ hw, vsi->seid, cld_filter, 1);
+ else
+ ret = i40e_aq_remove_cloud_filters(hw, vsi->seid,
&cld_filter->element, 1);
if (ret < 0) {
PMD_DRV_LOG(ERR, "Failed to delete a tunnel filter.");
@@ -10444,6 +10603,7 @@ i40e_tunnel_filter_restore(struct i40e_pf *pf)
*tunnel_list = &pf->tunnel.tunnel_list;
struct i40e_tunnel_filter *f;
struct i40e_aqc_add_rm_cloud_filt_elem_ext cld_filter;
+ bool big_buffer = 0;
TAILQ_FOREACH(f, tunnel_list, rules) {
memset(&cld_filter, 0, sizeof(cld_filter));
@@ -10459,8 +10619,20 @@ i40e_tunnel_filter_restore(struct i40e_pf *pf)
f->input.general_fields,
sizeof(f->input.general_fields));
- i40e_aq_add_cloud_filters(hw, vsi->seid,
- &cld_filter.element, 1);
+ if (((f->input.flags &
+ I40E_AQC_ADD_CLOUD_FILTER_TEID_MPLSoUDP) ==
+ I40E_AQC_ADD_CLOUD_FILTER_TEID_MPLSoUDP) ||
+ ((f->input.flags &
+ I40E_AQC_ADD_CLOUD_FILTER_TEID_MPLSoGRE) ==
+ I40E_AQC_ADD_CLOUD_FILTER_TEID_MPLSoGRE))
+ big_buffer = 1;
+
+ if (big_buffer)
+ i40e_aq_add_cloud_filters_big_buffer(hw,
+ vsi->seid, &cld_filter, 1);
+ else
+ i40e_aq_add_cloud_filters(hw, vsi->seid,
+ &cld_filter.element, 1);
}
}
diff --git a/drivers/net/i40e/i40e_ethdev.h b/drivers/net/i40e/i40e_ethdev.h
index dec1bd6..a8ecea4 100644
--- a/drivers/net/i40e/i40e_ethdev.h
+++ b/drivers/net/i40e/i40e_ethdev.h
@@ -501,6 +501,14 @@ struct i40e_ethertype_rule {
/* Tunnel filter number HW supports */
#define I40E_MAX_TUNNEL_FILTER_NUM 400
+#define I40E_AQC_REPLACE_CLOUD_CMD_INPUT_FV_TEID_WORD0 44
+#define I40E_AQC_REPLACE_CLOUD_CMD_INPUT_FV_TEID_WORD1 45
+#define I40E_AQC_ADD_CLOUD_TNL_TYPE_MPLSoUDP 8
+#define I40E_AQC_ADD_CLOUD_TNL_TYPE_MPLSoGRE 9
+#define I40E_AQC_ADD_CLOUD_FILTER_TEID_MPLSoUDP 0x11
+#define I40E_AQC_ADD_CLOUD_FILTER_TEID_MPLSoGRE 0x12
+#define I40E_AQC_ADD_L1_FILTER_TEID_MPLS 0x11
+
enum i40e_tunnel_iptype {
I40E_TUNNEL_IPTYPE_IPV4,
I40E_TUNNEL_IPTYPE_IPV6,
@@ -665,6 +673,7 @@ struct i40e_pf {
/* The floating enable flag for the specific VF */
bool floating_veb_list[I40E_MAX_VF];
struct i40e_flow_list flow_list;
+ bool mpls_replace_flag; /* 1 - MPLS filter replace is done */
};
enum pending_msg {
diff --git a/drivers/net/i40e/i40e_flow.c b/drivers/net/i40e/i40e_flow.c
index d5c705e..dc456c3 100644
--- a/drivers/net/i40e/i40e_flow.c
+++ b/drivers/net/i40e/i40e_flow.c
@@ -1935,6 +1935,7 @@ i40e_flow_destroy_tunnel_filter(struct i40e_pf *pf,
struct i40e_aqc_add_rm_cloud_filt_elem_ext cld_filter;
struct i40e_tunnel_rule *tunnel_rule = &pf->tunnel;
struct i40e_tunnel_filter *node;
+ bool big_buffer = 0;
int ret = 0;
memset(&cld_filter, 0, sizeof(cld_filter));
@@ -1950,8 +1951,18 @@ i40e_flow_destroy_tunnel_filter(struct i40e_pf *pf,
filter->input.general_fields,
sizeof(cld_filter.general_fields));
- ret = i40e_aq_remove_cloud_filters(hw, vsi->seid,
- &cld_filter.element, 1);
+ if (((filter->input.flags & I40E_AQC_ADD_CLOUD_FILTER_TEID_MPLSoUDP) ==
+ I40E_AQC_ADD_CLOUD_FILTER_TEID_MPLSoUDP) ||
+ ((filter->input.flags & I40E_AQC_ADD_CLOUD_FILTER_TEID_MPLSoGRE) ==
+ I40E_AQC_ADD_CLOUD_FILTER_TEID_MPLSoGRE))
+ big_buffer = 1;
+
+ if (big_buffer)
+ ret = i40e_aq_remove_cloud_filters_big_buffer(hw, vsi->seid,
+ &cld_filter, 1);
+ else
+ ret = i40e_aq_remove_cloud_filters(hw, vsi->seid,
+ &cld_filter.element, 1);
if (ret < 0)
return -ENOTSUP;
--
2.5.5
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [dpdk-dev] [PATCH v6 0/4] add support for MPLS tunnel filter
2017-03-30 8:29 [dpdk-dev] [PATCH v6 0/4] add support for MPLS tunnel filter Beilei Xing
` (3 preceding siblings ...)
2017-03-30 8:29 ` [dpdk-dev] [PATCH v6 4/4] net/i40e: enable tunnel filter for MPLS Beilei Xing
@ 2017-03-30 17:04 ` Ferruh Yigit
4 siblings, 0 replies; 6+ messages in thread
From: Ferruh Yigit @ 2017-03-30 17:04 UTC (permalink / raw)
To: Beilei Xing, jingjing.wu; +Cc: helin.zhang, bernard.iremonger, dev
On 3/30/2017 9:29 AM, Beilei Xing wrote:
> This patchset adds support for MPLSoGRE and MPLSoUDP
> tunnel filters.
> I40e NICs can't recongnize MPLS tunnel packets by
> default, so need to load a profile to FW first, then
> MPLS tunnel packets can be recongnized with packet
> type 61 and 63.
> It depends on pipeline personalization profile support
> and changes of tunnel filter function.
>
> v6 changes:
> Change MPLS configuration with the FW modification.
>
> v5 changes:
> Rework MPLS parse function.
> Add replace filter flag for MPLS.
>
> v4 changes:
> Move replace functions to i40e_ethdev.c.
>
> v3 changes:
> Add big_buffer condition to this patchset.
> Change some descriptions for new MPLS and GRE items.
> Fix default mask error for MPLS label.
>
> Beilei Xing (4):
> ethdev: add MPLS and GRE items
> app/testpmd: add MPLS and GRE fields to flow command
> net/i40e: add MPLS parsing function
> net/i40e: enable tunnel filter for MPLS
Series applied to dpdk-next-net/master, thanks.
^ permalink raw reply [flat|nested] 6+ messages in thread