DPDK patches and discussions
 help / color / mirror / Atom feed
* [dpdk-dev] [PATCH v2 0/2] Added vxlan/nvgre encap/decap support to testpmd
@ 2018-05-11 17:13 Mohammad Abdul Awal
  2018-05-11 17:14 ` [dpdk-dev] [PATCH v2 1/2] app/testpmd: enabled vxlan and nvgre encap/decap support for rte_flow Mohammad Abdul Awal
  2018-05-11 17:14 ` [dpdk-dev] [PATCH v2 2/2] doc/guides: updated testpmd app user guide for vxlan/nvgre encap/decap Mohammad Abdul Awal
  0 siblings, 2 replies; 9+ messages in thread
From: Mohammad Abdul Awal @ 2018-05-11 17:13 UTC (permalink / raw)
  To: dev, bernard.iremonger, adrien.mazarguil

Changes in v2:
* Added documentation in testpmd user guide.
* Added vlan header for vxlan/nvgre encap.
* Fixed other comments. 

In this patch set we have enabled testpmd application with ability to create
a flow with vxlan/nvgre tunnel types and with encapsulation/decapsulation
functionalities.

We have also updated the testpmd user guide documentation with how to used new
action types RTE_FLOW_ACTION_VXLAN_ENCAP, RTE_FLOW_ACTION_VXLAN_DECAP,
RTE_FLOW_ACTION_NVGRE_ENCAP, RTE_FLOW_ACTION_NVGRE_DECAP capabilities.

Mohammad Abdul Awal (2):
  app/testpmd: enabled vxlan and nvgre encap/decap support for rte_flow
  doc/guides: updated testpmd app user guide for vxlan/nvgre encap/decap

 app/test-pmd/cmdline_flow.c                 | 937 ++++++++++++++++++++++++++++
 doc/guides/testpmd_app_ug/testpmd_funcs.rst |  50 ++
 2 files changed, 987 insertions(+)

-- 
2.7.4

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [dpdk-dev] [PATCH v2 1/2] app/testpmd: enabled vxlan and nvgre encap/decap support for rte_flow
  2018-05-11 17:13 [dpdk-dev] [PATCH v2 0/2] Added vxlan/nvgre encap/decap support to testpmd Mohammad Abdul Awal
@ 2018-05-11 17:14 ` Mohammad Abdul Awal
  2018-05-14 11:14   ` Iremonger, Bernard
  2018-05-11 17:14 ` [dpdk-dev] [PATCH v2 2/2] doc/guides: updated testpmd app user guide for vxlan/nvgre encap/decap Mohammad Abdul Awal
  1 sibling, 1 reply; 9+ messages in thread
From: Mohammad Abdul Awal @ 2018-05-11 17:14 UTC (permalink / raw)
  To: dev, bernard.iremonger, adrien.mazarguil

We have enabled testpmd application with ability to create a flow with
vxlan/nvgre tunnel types and with encapsulation/decapsulation
functionalities.

Signed-off-by: Mohammad Abdul Awal <mohammad.abdul.awal@intel.com>
---
 app/test-pmd/cmdline_flow.c | 937 ++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 937 insertions(+)

diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
index 5754e78..5ffc127 100644
--- a/app/test-pmd/cmdline_flow.c
+++ b/app/test-pmd/cmdline_flow.c
@@ -237,6 +237,48 @@ enum index {
 	ACTION_OF_POP_MPLS_ETHERTYPE,
 	ACTION_OF_PUSH_MPLS,
 	ACTION_OF_PUSH_MPLS_ETHERTYPE,
+	ACTION_VXLAN_ENCAP,
+	ACTION_VXLAN_ENCAP_ETH_DST,
+	ACTION_VXLAN_ENCAP_ETH_DST_VALUE,
+	ACTION_VXLAN_ENCAP_ETH_SRC,
+	ACTION_VXLAN_ENCAP_ETH_SRC_VALUE,
+	ACTION_VXLAN_ENCAP_ETH_TYPE,
+	ACTION_VXLAN_ENCAP_ETH_TYPE_VALUE,
+	ACTION_VXLAN_ENCAP_VLAN_TCI,
+	ACTION_VXLAN_ENCAP_VLAN_TCI_VALUE,
+	ACTION_VXLAN_ENCAP_IPV4_DST,
+	ACTION_VXLAN_ENCAP_IPV4_DST_VALUE,
+	ACTION_VXLAN_ENCAP_IPV4_SRC,
+	ACTION_VXLAN_ENCAP_IPV4_SRC_VALUE,
+	ACTION_VXLAN_ENCAP_IPV4_PROTO,
+	ACTION_VXLAN_ENCAP_IPV4_PROTO_VALUE,
+	ACTION_VXLAN_ENCAP_UDP_SRC,
+	ACTION_VXLAN_ENCAP_UDP_SRC_VALUE,
+	ACTION_VXLAN_ENCAP_UDP_DST,
+	ACTION_VXLAN_ENCAP_UDP_DST_VALUE,
+	ACTION_VXLAN_ENCAP_VXLAN_VNI,
+	ACTION_VXLAN_ENCAP_VXLAN_VNI_VALUE,
+	ACTION_VXLAN_ENCAP_END,
+	ACTION_VXLAN_DECAP,
+	ACTION_NVGRE_ENCAP,
+	ACTION_NVGRE_ENCAP_ETH_DST,
+	ACTION_NVGRE_ENCAP_ETH_DST_VALUE,
+	ACTION_NVGRE_ENCAP_ETH_SRC,
+	ACTION_NVGRE_ENCAP_ETH_SRC_VALUE,
+	ACTION_NVGRE_ENCAP_ETH_TYPE,
+	ACTION_NVGRE_ENCAP_ETH_TYPE_VALUE,
+	ACTION_NVGRE_ENCAP_VLAN_TCI,
+	ACTION_NVGRE_ENCAP_VLAN_TCI_VALUE,
+	ACTION_NVGRE_ENCAP_IPV4_DST,
+	ACTION_NVGRE_ENCAP_IPV4_DST_VALUE,
+	ACTION_NVGRE_ENCAP_IPV4_SRC,
+	ACTION_NVGRE_ENCAP_IPV4_SRC_VALUE,
+	ACTION_NVGRE_ENCAP_IPV4_PROTO,
+	ACTION_NVGRE_ENCAP_IPV4_PROTO_VALUE,
+	ACTION_NVGRE_ENCAP_NVGRE_VSNI,
+	ACTION_NVGRE_ENCAP_NVGRE_VSNI_VALUE,
+	ACTION_NVGRE_ENCAP_END,
+	ACTION_NVGRE_DECAP,
 };
 
 /** Maximum size for pattern in struct rte_flow_item_raw. */
@@ -256,6 +298,30 @@ struct action_rss_data {
 	uint16_t queue[ACTION_RSS_QUEUE_NUM];
 };
 
+#define ACTION_VXLAN_ENCAP_MAX_PATTERN 5
+#define ACTION_NVGRE_ENCAP_MAX_PATTERN 4
+
+struct action_vxlan_encap_data {
+	struct rte_flow_action_vxlan_encap conf;
+	struct rte_flow_item pattern[ACTION_VXLAN_ENCAP_MAX_PATTERN];
+	struct rte_flow_item_eth eth;
+	struct rte_flow_item_vlan vlan;
+	struct rte_flow_item_ipv4 ipv4;
+	struct rte_flow_item_udp udp;
+	struct rte_flow_item_vxlan vxlan;
+	uint32_t hdr_flags;
+};
+
+struct action_nvgre_encap_data {
+	struct rte_flow_action_nvgre_encap conf;
+	struct rte_flow_item pattern[ACTION_NVGRE_ENCAP_MAX_PATTERN];
+	struct rte_flow_item_eth eth;
+	struct rte_flow_item_vlan vlan;
+	struct rte_flow_item_ipv4 ipv4;
+	struct rte_flow_item_nvgre nvgre;
+	uint32_t hdr_flags;
+};
+
 /** Maximum number of subsequent tokens and arguments on the stack. */
 #define CTX_STACK_SIZE 16
 
@@ -383,6 +449,13 @@ struct token {
 		.size = (s), \
 	})
 
+#define ARGS_ENTRY_ARB_HTON(o, s) \
+	(&(const struct arg){ \
+		.hton = 1, \
+		.offset = (o), \
+		.size = (s), \
+	})
+
 /** Same as ARGS_ENTRY_ARB() with bounded values. */
 #define ARGS_ENTRY_ARB_BOUNDED(o, s, i, a) \
 	(&(const struct arg){ \
@@ -773,6 +846,10 @@ static const enum index next_action[] = {
 	ACTION_OF_SET_VLAN_PCP,
 	ACTION_OF_POP_MPLS,
 	ACTION_OF_PUSH_MPLS,
+	ACTION_VXLAN_ENCAP,
+	ACTION_VXLAN_DECAP,
+	ACTION_NVGRE_ENCAP,
+	ACTION_NVGRE_DECAP,
 	ZERO,
 };
 
@@ -874,6 +951,46 @@ static const enum index action_jump[] = {
 	ZERO,
 };
 
+static const enum index action_vxlan_encap[] = {
+	ACTION_VXLAN_ENCAP_ETH_DST,
+	ACTION_VXLAN_ENCAP_ETH_SRC,
+	ACTION_VXLAN_ENCAP_ETH_TYPE,
+	ACTION_VXLAN_ENCAP_VLAN_TCI,
+	ACTION_VXLAN_ENCAP_IPV4_DST,
+	ACTION_VXLAN_ENCAP_IPV4_SRC,
+	ACTION_VXLAN_ENCAP_IPV4_PROTO,
+	ACTION_VXLAN_ENCAP_UDP_DST,
+	ACTION_VXLAN_ENCAP_UDP_SRC,
+	ACTION_VXLAN_ENCAP_VXLAN_VNI,
+	ACTION_VXLAN_ENCAP_END,
+	ACTION_NEXT,
+	ZERO,
+};
+
+static const enum index action_vxlan_decap[] = {
+	ACTION_NEXT,
+	ZERO,
+};
+
+static const enum index action_nvgre_encap[] = {
+	ACTION_NVGRE_ENCAP_ETH_DST,
+	ACTION_NVGRE_ENCAP_ETH_SRC,
+	ACTION_NVGRE_ENCAP_ETH_TYPE,
+	ACTION_NVGRE_ENCAP_VLAN_TCI,
+	ACTION_NVGRE_ENCAP_IPV4_DST,
+	ACTION_NVGRE_ENCAP_IPV4_SRC,
+	ACTION_NVGRE_ENCAP_IPV4_PROTO,
+	ACTION_NVGRE_ENCAP_NVGRE_VSNI,
+	ACTION_NVGRE_ENCAP_END,
+	ACTION_NEXT,
+	ZERO,
+};
+
+static const enum index action_nvgre_decap[] = {
+	ACTION_NEXT,
+	ZERO,
+};
+
 static int parse_init(struct context *, const struct token *,
 		      const char *, unsigned int,
 		      void *, unsigned int);
@@ -896,6 +1013,42 @@ static int parse_vc_action_rss_type(struct context *, const struct token *,
 static int parse_vc_action_rss_queue(struct context *, const struct token *,
 				     const char *, unsigned int, void *,
 				     unsigned int);
+static int parse_vc_action_vxlan_encap(struct context *, const struct token *,
+				       const char *, unsigned int, void *,
+				       unsigned int);
+static int parse_vc_action_vxlan_decap(struct context *, const struct token *,
+				       const char *, unsigned int, void *,
+				       unsigned int);
+static int parse_vc_action_vxlan_encap_fields(struct context *,
+					      const struct token *,
+					      const char *, unsigned int,
+					      void *, unsigned int);
+static int parse_vc_action_vxlan_encap_fields_value(struct context *,
+						    const struct token *,
+						    const char *, unsigned int,
+						    void *, unsigned int);
+static int parse_vc_action_vxlan_encap_end(struct context *,
+					   const struct token *,
+					   const char *, unsigned int,
+					   void *, unsigned int);
+static int parse_vc_action_nvgre_encap(struct context *, const struct token *,
+				       const char *, unsigned int, void *,
+				       unsigned int);
+static int parse_vc_action_nvgre_decap(struct context *, const struct token *,
+				       const char *, unsigned int, void *,
+				       unsigned int);
+static int parse_vc_action_nvgre_encap_fields(struct context *,
+					      const struct token *,
+					      const char *, unsigned int,
+					      void *, unsigned int);
+static int parse_vc_action_nvgre_encap_fields_value(struct context *,
+						    const struct token *,
+						    const char *, unsigned int,
+						    void *, unsigned int);
+static int parse_vc_action_nvgre_encap_end(struct context *,
+					   const struct token *,
+					   const char *, unsigned int,
+					   void *, unsigned int);
 static int parse_destroy(struct context *, const struct token *,
 			 const char *, unsigned int,
 			 void *, unsigned int);
@@ -2362,6 +2515,282 @@ static const struct token token_list[] = {
 			      ethertype)),
 		.call = parse_vc_conf,
 	},
+	[ACTION_VXLAN_ENCAP] = {
+		.name = "vxlan_encap",
+		.help = "encap flow with vxlan tunnel definition",
+		.priv = PRIV_ACTION(VXLAN_ENCAP,
+				    sizeof(struct action_vxlan_encap_data)),
+		.next = NEXT(action_vxlan_encap,
+				NEXT_ENTRY(ACTION_VXLAN_ENCAP_ETH_DST,
+					ACTION_VXLAN_ENCAP_ETH_SRC,
+					ACTION_VXLAN_ENCAP_ETH_TYPE,
+					ACTION_VXLAN_ENCAP_VLAN_TCI,
+					ACTION_VXLAN_ENCAP_IPV4_DST,
+					ACTION_VXLAN_ENCAP_IPV4_SRC,
+					ACTION_VXLAN_ENCAP_IPV4_PROTO,
+					ACTION_VXLAN_ENCAP_UDP_DST,
+					ACTION_VXLAN_ENCAP_UDP_SRC,
+					ACTION_VXLAN_ENCAP_VXLAN_VNI,
+					ACTION_VXLAN_ENCAP_END)),
+		.call = parse_vc_action_vxlan_encap,
+	},
+	[ACTION_VXLAN_DECAP] = {
+		.name = "vxlan_decap",
+		.help = "decap flow with vxlan tunnel definition",
+		.priv = PRIV_ACTION(VXLAN_DECAP, 0),
+		.next = NEXT(action_vxlan_decap),
+		.call = parse_vc_action_vxlan_decap,
+	},
+	[ACTION_VXLAN_ENCAP_ETH_DST] = {
+		.name = "eth_dst",
+		.help = "destination MAC for vxlan tunnel",
+		.next = NEXT(action_vxlan_encap,
+			     NEXT_ENTRY(ACTION_VXLAN_ENCAP_ETH_DST_VALUE)),
+		.call = parse_vc_action_vxlan_encap_fields,
+	},
+	[ACTION_VXLAN_ENCAP_ETH_DST_VALUE] = {
+		.name = "eth_dst_value",
+		.help = "destination MAC for vxlan tunnel",
+		.call = parse_vc_action_vxlan_encap_fields_value,
+	},
+	[ACTION_VXLAN_ENCAP_ETH_SRC] = {
+		.name = "eth_src",
+		.help = "source MAC for vxlan tunnel",
+		.next = NEXT(action_vxlan_encap,
+			     NEXT_ENTRY(ACTION_VXLAN_ENCAP_ETH_SRC_VALUE)),
+		.call = parse_vc_action_vxlan_encap_fields,
+	},
+	[ACTION_VXLAN_ENCAP_ETH_SRC_VALUE] = {
+		.name = "eth_src_value",
+		.help = "source MAC for vxlan tunnel",
+		.call = parse_vc_action_vxlan_encap_fields_value,
+	},
+	[ACTION_VXLAN_ENCAP_ETH_TYPE] = {
+		.name = "eth_type",
+		.help = "eth type for vxlan tunnel",
+		.next = NEXT(action_vxlan_encap,
+			     NEXT_ENTRY(ACTION_VXLAN_ENCAP_ETH_TYPE_VALUE)),
+		.call = parse_vc_action_vxlan_encap_fields,
+	},
+	[ACTION_VXLAN_ENCAP_ETH_TYPE_VALUE] = {
+		.name = "eth_type_value",
+		.help = "eth type for vxlan tunnel",
+		.call = parse_vc_action_vxlan_encap_fields_value,
+	},
+	[ACTION_VXLAN_ENCAP_VLAN_TCI] = {
+		.name = "vlan_tci",
+		.help = "vlan tci for vxlan tunnel",
+		.next = NEXT(action_vxlan_encap,
+			     NEXT_ENTRY(ACTION_VXLAN_ENCAP_VLAN_TCI_VALUE)),
+		.call = parse_vc_action_vxlan_encap_fields,
+	},
+	[ACTION_VXLAN_ENCAP_VLAN_TCI_VALUE] = {
+		.name = "vlan_tci_value",
+		.help = "vlan tci for vxlan tunnel",
+		.call = parse_vc_action_vxlan_encap_fields_value,
+	},
+	[ACTION_VXLAN_ENCAP_IPV4_DST] = {
+		.name = "ipv4_dst",
+		.help = "destination ipv4 IP for vxlan tunnel",
+		.next = NEXT(action_vxlan_encap,
+			     NEXT_ENTRY(ACTION_VXLAN_ENCAP_IPV4_DST_VALUE)),
+		.call = parse_vc_action_vxlan_encap_fields,
+	},
+	[ACTION_VXLAN_ENCAP_IPV4_DST_VALUE] = {
+		.name = "ipv4_dst_value",
+		.help = "destination ipv4 IP for vxlan tunnel",
+		.call = parse_vc_action_vxlan_encap_fields_value,
+	},
+	[ACTION_VXLAN_ENCAP_IPV4_SRC] = {
+		.name = "ipv4_src",
+		.help = "source ipv4 IP for vxlan tunnel",
+		.next = NEXT(action_vxlan_encap,
+			     NEXT_ENTRY(ACTION_VXLAN_ENCAP_IPV4_SRC_VALUE)),
+		.call = parse_vc_action_vxlan_encap_fields,
+	},
+	[ACTION_VXLAN_ENCAP_IPV4_SRC_VALUE] = {
+		.name = "ipv4_src_value",
+		.help = "source ipv4 IP for vxlan tunnel",
+		.call = parse_vc_action_vxlan_encap_fields_value,
+	},
+	[ACTION_VXLAN_ENCAP_IPV4_PROTO] = {
+		.name = "ipv4_proto",
+		.help = "ipv4 proto for vxlan tunnel",
+		.next = NEXT(action_vxlan_encap,
+			     NEXT_ENTRY(ACTION_VXLAN_ENCAP_IPV4_PROTO_VALUE)),
+		.call = parse_vc_action_vxlan_encap_fields,
+	},
+	[ACTION_VXLAN_ENCAP_IPV4_PROTO_VALUE] = {
+		.name = "ipv4_proto_value",
+		.help = "ipv4 proto for vxlan tunnel",
+		.call = parse_vc_action_vxlan_encap_fields_value,
+	},
+	[ACTION_VXLAN_ENCAP_UDP_DST] = {
+		.name = "udp_dst",
+		.help = "udp destination port for vxlan tunnel",
+		.next = NEXT(action_vxlan_encap,
+			     NEXT_ENTRY(ACTION_VXLAN_ENCAP_UDP_DST_VALUE)),
+		.call = parse_vc_action_vxlan_encap_fields,
+	},
+	[ACTION_VXLAN_ENCAP_UDP_DST_VALUE] = {
+		.name = "udp_dst_value",
+		.help = "udp destination port for vxlan tunnel",
+		.call = parse_vc_action_vxlan_encap_fields_value,
+	},
+	[ACTION_VXLAN_ENCAP_UDP_SRC] = {
+		.name = "udp_src",
+		.help = "udp source port for vxlan tunnel",
+		.next = NEXT(action_vxlan_encap,
+			     NEXT_ENTRY(ACTION_VXLAN_ENCAP_UDP_SRC_VALUE)),
+		.call = parse_vc_action_vxlan_encap_fields,
+	},
+	[ACTION_VXLAN_ENCAP_UDP_SRC_VALUE] = {
+		.name = "udp_src_value",
+		.help = "udp source port for vxlan tunnel",
+		.call = parse_vc_action_vxlan_encap_fields_value,
+	},
+	[ACTION_VXLAN_ENCAP_VXLAN_VNI] = {
+		.name = "vxlan_vni",
+		.help = "vxlan vni for vxlan tunnel",
+		.next = NEXT(action_vxlan_encap,
+			     NEXT_ENTRY(ACTION_VXLAN_ENCAP_VXLAN_VNI_VALUE)),
+		.call = parse_vc_action_vxlan_encap_fields,
+	},
+	[ACTION_VXLAN_ENCAP_VXLAN_VNI_VALUE] = {
+		.name = "vxlan_vni_value",
+		.help = "vxlan vni for vxlan tunnel",
+		.call = parse_vc_action_vxlan_encap_fields_value,
+	},
+	[ACTION_VXLAN_ENCAP_END] = {
+		.name = "end",
+		.help = "end of the pattern for vxlan encap",
+		.call = parse_vc_action_vxlan_encap_end,
+	},
+	[ACTION_NVGRE_ENCAP] = {
+		.name = "nvgre_encap",
+		.help = "encap flow with nvgre tunnel definition",
+		.priv = PRIV_ACTION(NVGRE_ENCAP,
+				    sizeof(struct action_nvgre_encap_data)),
+		.next = NEXT(action_nvgre_encap,
+				NEXT_ENTRY(ACTION_NVGRE_ENCAP_ETH_DST,
+					ACTION_NVGRE_ENCAP_ETH_SRC,
+					ACTION_NVGRE_ENCAP_ETH_TYPE,
+					ACTION_NVGRE_ENCAP_VLAN_TCI,
+					ACTION_NVGRE_ENCAP_IPV4_DST,
+					ACTION_NVGRE_ENCAP_IPV4_SRC,
+					ACTION_NVGRE_ENCAP_IPV4_PROTO,
+					ACTION_NVGRE_ENCAP_NVGRE_VSNI,
+					ACTION_NVGRE_ENCAP_END)),
+		.call = parse_vc_action_nvgre_encap,
+	},
+	[ACTION_NVGRE_DECAP] = {
+		.name = "nvgre_decap",
+		.help = "decap flow with nvgre tunnel definition",
+		.priv = PRIV_ACTION(NVGRE_DECAP, 0),
+		.next = NEXT(action_nvgre_decap),
+		.call = parse_vc_action_nvgre_decap,
+	},
+	[ACTION_NVGRE_ENCAP_ETH_DST] = {
+		.name = "eth_dst",
+		.help = "destination MAC for nvgre tunnel",
+		.next = NEXT(action_nvgre_encap,
+			     NEXT_ENTRY(ACTION_NVGRE_ENCAP_ETH_DST_VALUE)),
+		.call = parse_vc_action_nvgre_encap_fields,
+	},
+	[ACTION_NVGRE_ENCAP_ETH_DST_VALUE] = {
+		.name = "eth_dst_value",
+		.help = "destination MAC for nvgre tunnel",
+		.call = parse_vc_action_nvgre_encap_fields_value,
+	},
+	[ACTION_NVGRE_ENCAP_ETH_SRC] = {
+		.name = "eth_src",
+		.help = "source MAC for nvgre tunnel",
+		.next = NEXT(action_nvgre_encap,
+			     NEXT_ENTRY(ACTION_NVGRE_ENCAP_ETH_SRC_VALUE)),
+		.call = parse_vc_action_nvgre_encap_fields,
+	},
+	[ACTION_NVGRE_ENCAP_ETH_SRC_VALUE] = {
+		.name = "eth_src_value",
+		.help = "source MAC for nvgre tunnel",
+		.call = parse_vc_action_nvgre_encap_fields_value,
+	},
+	[ACTION_NVGRE_ENCAP_ETH_TYPE] = {
+		.name = "eth_type",
+		.help = "eth type for nvgre tunnel",
+		.next = NEXT(action_nvgre_encap,
+			     NEXT_ENTRY(ACTION_NVGRE_ENCAP_ETH_TYPE_VALUE)),
+		.call = parse_vc_action_nvgre_encap_fields,
+	},
+	[ACTION_NVGRE_ENCAP_ETH_TYPE_VALUE] = {
+		.name = "eth_type_value",
+		.help = "eth type for nvgre tunnel",
+		.call = parse_vc_action_nvgre_encap_fields_value,
+	},
+	[ACTION_NVGRE_ENCAP_VLAN_TCI] = {
+		.name = "vlan_tci",
+		.help = "vlan tci for nvgre tunnel",
+		.next = NEXT(action_nvgre_encap,
+			     NEXT_ENTRY(ACTION_NVGRE_ENCAP_VLAN_TCI_VALUE)),
+		.call = parse_vc_action_nvgre_encap_fields,
+	},
+	[ACTION_NVGRE_ENCAP_VLAN_TCI_VALUE] = {
+		.name = "vlan_tci_value",
+		.help = "vlan tci for nvgre tunnel",
+		.call = parse_vc_action_nvgre_encap_fields_value,
+	},
+	[ACTION_NVGRE_ENCAP_IPV4_DST] = {
+		.name = "ipv4_dst",
+		.help = "destination ipv4 IP for nvgre tunnel",
+		.next = NEXT(action_nvgre_encap,
+			     NEXT_ENTRY(ACTION_NVGRE_ENCAP_IPV4_DST_VALUE)),
+		.call = parse_vc_action_nvgre_encap_fields,
+	},
+	[ACTION_NVGRE_ENCAP_IPV4_DST_VALUE] = {
+		.name = "ipv4_dst_value",
+		.help = "destination ipv4 IP for nvgre tunnel",
+		.call = parse_vc_action_nvgre_encap_fields_value,
+	},
+	[ACTION_NVGRE_ENCAP_IPV4_SRC] = {
+		.name = "ipv4_src",
+		.help = "source ipv4 IP for nvgre tunnel",
+		.next = NEXT(action_nvgre_encap,
+			     NEXT_ENTRY(ACTION_NVGRE_ENCAP_IPV4_SRC_VALUE)),
+		.call = parse_vc_action_nvgre_encap_fields,
+	},
+	[ACTION_NVGRE_ENCAP_IPV4_SRC_VALUE] = {
+		.name = "ipv4_src_value",
+		.help = "source ipv4 IP for nvgre tunnel",
+		.call = parse_vc_action_nvgre_encap_fields_value,
+	},
+	[ACTION_NVGRE_ENCAP_IPV4_PROTO] = {
+		.name = "ipv4_proto",
+		.help = "ipv4 proto for nvgre tunnel",
+		.next = NEXT(action_nvgre_encap,
+			     NEXT_ENTRY(ACTION_NVGRE_ENCAP_IPV4_PROTO_VALUE)),
+		.call = parse_vc_action_nvgre_encap_fields,
+	},
+	[ACTION_NVGRE_ENCAP_IPV4_PROTO_VALUE] = {
+		.name = "ipv4_proto_value",
+		.help = "ipv4 proto for nvgre tunnel",
+		.call = parse_vc_action_nvgre_encap_fields_value,
+	},
+	[ACTION_NVGRE_ENCAP_NVGRE_VSNI] = {
+		.name = "nvgre_vsni",
+		.help = "nvgre vsni for NVGRE tunnel",
+		.next = NEXT(action_nvgre_encap,
+			     NEXT_ENTRY(ACTION_NVGRE_ENCAP_NVGRE_VSNI_VALUE)),
+		.call = parse_vc_action_nvgre_encap_fields,
+	},
+	[ACTION_NVGRE_ENCAP_NVGRE_VSNI_VALUE] = {
+		.name = "nvgre_vsni_value",
+		.help = "nvgre vsni for nvgre tunnel",
+		.call = parse_vc_action_nvgre_encap_fields_value,
+	},
+	[ACTION_NVGRE_ENCAP_END] = {
+		.name = "end",
+		.help = "end of the pattern for nvgre encap",
+		.call = parse_vc_action_nvgre_encap_end,
+	},
 };
 
 /** Remove and return last entry from argument stack. */
@@ -2924,6 +3353,514 @@ parse_vc_action_rss_queue(struct context *ctx, const struct token *token,
 	return len;
 }
 
+/** Parse VXLAN_ENCAP action. */
+static int __rte_unused
+parse_vc_action_vxlan_encap(struct context *ctx, const struct token *token,
+			    const char *str, unsigned int len,
+			    void *buf, unsigned int size)
+{
+	struct buffer *out = buf;
+	struct rte_flow_action *action;
+	struct action_vxlan_encap_data *data;
+	int ret;
+
+	ret = parse_vc(ctx, token, str, len, buf, size);
+	if (ret < 0)
+		return ret;
+	/* Nothing else to do if there is no buffer. */
+	if (!out)
+		return ret;
+	if (!out->args.vc.actions_n)
+		return -1;
+	action = &out->args.vc.actions[out->args.vc.actions_n - 1];
+	/* Point to selected object. */
+	ctx->object = out->args.vc.data;
+	ctx->objmask = NULL;
+	/* Set up default configuration. */
+	data = ctx->object;
+	data->conf.definition = data->pattern;
+	action->conf = &data->conf;
+
+	return ret;
+}
+
+/** Parse VXLAN_DECAP action. */
+static int
+parse_vc_action_vxlan_decap(struct context *ctx, const struct token *token,
+			    const char *str, unsigned int len,
+			    void *buf, unsigned int size)
+{
+	struct buffer *out = buf;
+	int ret;
+
+	ret = parse_vc(ctx, token, str, len, buf, size);
+	if (ret < 0)
+		return ret;
+	/* Nothing else to do if there is no buffer. */
+	if (!out)
+		return ret;
+	if (!out->args.vc.actions_n)
+		return -1;
+	/* Point to selected object. */
+	ctx->object = out->args.vc.data;
+	ctx->objmask = NULL;
+	return ret;
+}
+
+static uint32_t get_proto_index_using_flag(uint32_t flag)
+{
+	uint32_t c = 0, i = 0;
+	uint32_t supported_ptypes[] = {
+					RTE_PTYPE_L2_ETHER,
+					RTE_PTYPE_L2_ETHER_VLAN,
+					RTE_PTYPE_L3_IPV4,
+					RTE_PTYPE_L4_UDP,
+					RTE_PTYPE_TUNNEL_VXLAN,
+					RTE_PTYPE_TUNNEL_NVGRE
+				       };
+
+	for (i = 0; i != RTE_DIM(supported_ptypes); i++) {
+		if (supported_ptypes[i] & flag)
+			c++;
+	}
+	c = (c > 0) ? (c - 1) : 0;
+
+	return c;
+}
+
+/** Parse VXLAN_ENCAP action pattern fields. */
+static int __rte_unused
+parse_vc_action_vxlan_encap_fields(struct context *ctx,
+				   const struct token *token,
+				   const char *str, unsigned int len,
+				   void *buf, unsigned int size)
+{
+	struct action_vxlan_encap_data *data;
+	uint32_t p_index;
+
+	(void)buf;
+	(void)size;
+	/* Token name must match. */
+	if (parse_default(ctx, token, str, len, NULL, 0) < 0)
+		return -1;
+	if (!ctx->object)
+		return len;
+	switch (ctx->curr) {
+	case ACTION_VXLAN_ENCAP_ETH_DST:
+	case ACTION_VXLAN_ENCAP_ETH_SRC:
+	case ACTION_VXLAN_ENCAP_ETH_TYPE:
+		data = ctx->object;
+		data->hdr_flags |= RTE_PTYPE_L2_ETHER;
+		p_index = get_proto_index_using_flag(data->hdr_flags);
+		data->pattern[p_index].spec = &data->eth;
+		data->pattern[p_index].mask = &rte_flow_item_eth_mask;
+		data->pattern[p_index].type = RTE_FLOW_ITEM_TYPE_ETH;
+		break;
+	case ACTION_VXLAN_ENCAP_VLAN_TCI:
+		data = ctx->object;
+		data->hdr_flags |= RTE_PTYPE_L2_ETHER_VLAN;
+		p_index = get_proto_index_using_flag(data->hdr_flags);
+		data->pattern[p_index].spec = &data->vlan;
+		data->pattern[p_index].mask = &rte_flow_item_vlan_mask;
+		data->pattern[p_index].type = RTE_FLOW_ITEM_TYPE_VLAN;
+		break;
+	case ACTION_VXLAN_ENCAP_IPV4_DST:
+	case ACTION_VXLAN_ENCAP_IPV4_SRC:
+	case ACTION_VXLAN_ENCAP_IPV4_PROTO:
+		data = ctx->object;
+		data->hdr_flags |= RTE_PTYPE_L3_IPV4;
+		p_index = get_proto_index_using_flag(data->hdr_flags);
+		data->pattern[p_index].spec = &data->ipv4;
+		data->pattern[p_index].mask = &rte_flow_item_ipv4_mask;
+		data->pattern[p_index].type = RTE_FLOW_ITEM_TYPE_IPV4;
+		break;
+	case ACTION_VXLAN_ENCAP_UDP_DST:
+	case ACTION_VXLAN_ENCAP_UDP_SRC:
+		data = ctx->object;
+		data->hdr_flags |= RTE_PTYPE_L4_UDP;
+		p_index = get_proto_index_using_flag(data->hdr_flags);
+		data->pattern[p_index].spec = &data->udp;
+		data->pattern[p_index].mask = &rte_flow_item_udp_mask;
+		data->pattern[p_index].type = RTE_FLOW_ITEM_TYPE_UDP;
+		break;
+	case ACTION_VXLAN_ENCAP_VXLAN_VNI:
+		data = ctx->object;
+		data->hdr_flags |= RTE_PTYPE_TUNNEL_VXLAN;
+		p_index = get_proto_index_using_flag(data->hdr_flags);
+		data->pattern[p_index].spec = &data->vxlan;
+		data->pattern[p_index].mask = &rte_flow_item_vxlan_mask;
+		data->pattern[p_index].type = RTE_FLOW_ITEM_TYPE_VXLAN;
+		break;
+	default:
+		return -1;
+	}
+
+	return len;
+}
+
+/** Parse VXLAN_ENCAP action pattern fields value. */
+static int __rte_unused
+parse_vc_action_vxlan_encap_fields_value(struct context *ctx,
+					 const struct token *token,
+					 const char *str, unsigned int len,
+					 void *buf, unsigned int size)
+{
+	struct action_vxlan_encap_data *data;
+	struct ether_addr mac;
+	char str2[len + 1];
+	struct in_addr ip4;
+	uint16_t val1;
+	uint32_t val2;
+	int ret;
+
+	(void)token;
+	(void)buf;
+	if (!ctx->object)
+		return len;
+	data = ctx->object;
+	switch (ctx->curr) {
+	case ACTION_VXLAN_ENCAP_ETH_DST_VALUE:
+		ret = cmdline_parse_etheraddr(NULL, str, &mac, size);
+		if (ret < 0 || (unsigned int)ret != len)
+			return -1;
+		memcpy(&data->eth.dst, &mac, sizeof(mac));
+		break;
+	case ACTION_VXLAN_ENCAP_ETH_SRC_VALUE:
+		ret = cmdline_parse_etheraddr(NULL, str, &mac, size);
+		if (ret < 0 || (unsigned int)ret != len)
+			return -1;
+		memcpy(&data->eth.src, &mac, sizeof(mac));
+		break;
+	case ACTION_VXLAN_ENCAP_ETH_TYPE_VALUE:
+		memcpy(str2, str, len);
+		str2[len] = '\0';
+		val1 = strtoul(str2, NULL, 0);
+		if (val1 == 0)
+			return -1;
+		data->eth.type = htons(val1);
+		break;
+	case ACTION_VXLAN_ENCAP_VLAN_TCI_VALUE:
+		memcpy(str2, str, len);
+		str2[len] = '\0';
+		val1 = strtoul(str2, NULL, 0);
+		if (val1 == 0)
+			return -1;
+		data->vlan.tci = htons(val1);
+		break;
+	case ACTION_VXLAN_ENCAP_IPV4_DST_VALUE:
+		memcpy(str2, str, len);
+		str2[len] = '\0';
+		ret = inet_pton(AF_INET, str2, &ip4);
+		if (ret != 1)
+			return -1;
+		memcpy(&data->ipv4.hdr.dst_addr, &ip4, sizeof(ip4));
+		break;
+	case ACTION_VXLAN_ENCAP_IPV4_SRC_VALUE:
+		memcpy(str2, str, len);
+		str2[len] = '\0';
+		ret = inet_pton(AF_INET, str2, &ip4);
+		if (ret != 1)
+			return -1;
+		memcpy(&data->ipv4.hdr.src_addr, &ip4, sizeof(ip4));
+		break;
+	case ACTION_VXLAN_ENCAP_IPV4_PROTO_VALUE:
+		memcpy(str2, str, len);
+		str2[len] = '\0';
+		val1 = strtoul(str2, NULL, 0);
+		if (val1 == 0)
+			return -1;
+		data->ipv4.hdr.next_proto_id = val1;
+		break;
+	case ACTION_VXLAN_ENCAP_UDP_DST_VALUE:
+		memcpy(str2, str, len);
+		str2[len] = '\0';
+		val1 = strtoul(str2, NULL, 0);
+		if (val1 == 0)
+			return -1;
+		data->udp.hdr.dst_port = htons(val1);
+		break;
+	case ACTION_VXLAN_ENCAP_UDP_SRC_VALUE:
+		memcpy(str2, str, len);
+		str2[len] = '\0';
+		val1 = strtoul(str2, NULL, 0);
+		if (val1 == 0)
+			return -1;
+		data->udp.hdr.src_port = htons(val1);
+		break;
+	case ACTION_VXLAN_ENCAP_VXLAN_VNI_VALUE:
+		memcpy(str2, str, len);
+		str2[len] = '\0';
+		val2 = strtoul(str2, NULL, 0);
+		if (val2 == 0)
+			return -1;
+		data->vxlan.vni[0] = (uint8_t)((val2 >> 16) & 0xff);
+		data->vxlan.vni[1] = (uint8_t)((val2 >> 8) & 0xff);
+		data->vxlan.vni[2] = (uint8_t)(val2 & 0xff);
+		break;
+	default:
+		return -1;
+	}
+
+	return len;
+}
+
+/** Parse VXLAN_ENCAP action pattern end. */
+static int __rte_unused
+parse_vc_action_vxlan_encap_end(struct context *ctx,
+				const struct token *token,
+				const char *str, unsigned int len,
+				void *buf, unsigned int size)
+{
+	struct action_vxlan_encap_data *data;
+	uint32_t p_index;
+
+	(void)buf;
+	(void)size;
+	/* Token name must match. */
+	if (parse_default(ctx, token, str, len, NULL, 0) < 0)
+		return -1;
+	if (ctx->curr != ACTION_VXLAN_ENCAP_END)
+		return -1;
+	if (!ctx->object)
+		return len;
+	data = ctx->object;
+	p_index = get_proto_index_using_flag(data->hdr_flags);
+	data->pattern[p_index + 1].type = RTE_FLOW_ITEM_TYPE_END;
+
+	return len;
+}
+
+/** Parse NVGRE_ENCAP action. */
+static int __rte_unused
+parse_vc_action_nvgre_encap(struct context *ctx, const struct token *token,
+			    const char *str, unsigned int len,
+			    void *buf, unsigned int size)
+{
+	struct buffer *out = buf;
+	struct rte_flow_action *action;
+	struct action_nvgre_encap_data *data;
+	int ret;
+
+	ret = parse_vc(ctx, token, str, len, buf, size);
+	if (ret < 0)
+		return ret;
+	/* Nothing else to do if there is no buffer. */
+	if (!out)
+		return ret;
+	if (!out->args.vc.actions_n)
+		return -1;
+	action = &out->args.vc.actions[out->args.vc.actions_n - 1];
+	/* Point to selected object. */
+	ctx->object = out->args.vc.data;
+	ctx->objmask = NULL;
+	/* Set up default configuration. */
+	data = ctx->object;
+	data->conf.definition = data->pattern;
+	action->conf = &data->conf;
+
+	return ret;
+}
+
+/** Parse NVGRE_DECAP action. */
+static int __rte_unused
+parse_vc_action_nvgre_decap(struct context *ctx, const struct token *token,
+		    const char *str, unsigned int len,
+		    void *buf, unsigned int size)
+{
+	struct buffer *out = buf;
+	int ret;
+
+	ret = parse_vc(ctx, token, str, len, buf, size);
+	if (ret < 0)
+		return ret;
+	/* Nothing else to do if there is no buffer. */
+	if (!out)
+		return ret;
+	if (!out->args.vc.actions_n)
+		return -1;
+	/* Point to selected object. */
+	ctx->object = out->args.vc.data;
+	ctx->objmask = NULL;
+	return ret;
+}
+
+/** Parse NVGRE_ENCAP action pattern fields. */
+static int __rte_unused
+parse_vc_action_nvgre_encap_fields(struct context *ctx,
+				   const struct token *token,
+				   const char *str, unsigned int len,
+				   void *buf, unsigned int size)
+{
+	struct action_nvgre_encap_data *data;
+	uint32_t p_index;
+
+	(void)buf;
+	(void)size;
+	/* Token name must match. */
+	if (parse_default(ctx, token, str, len, NULL, 0) < 0)
+		return -1;
+	if (!ctx->object)
+		return len;
+	switch (ctx->curr) {
+	case ACTION_NVGRE_ENCAP_ETH_DST:
+	case ACTION_NVGRE_ENCAP_ETH_SRC:
+	case ACTION_NVGRE_ENCAP_ETH_TYPE:
+		data = ctx->object;
+		data->hdr_flags |= RTE_PTYPE_L2_ETHER;
+		p_index = get_proto_index_using_flag(data->hdr_flags);
+		data->pattern[p_index].spec = &data->eth;
+		data->pattern[p_index].mask = &rte_flow_item_eth_mask;
+		data->pattern[p_index].type = RTE_FLOW_ITEM_TYPE_ETH;
+		break;
+	case ACTION_NVGRE_ENCAP_VLAN_TCI:
+		data = ctx->object;
+		data->hdr_flags |= RTE_PTYPE_L2_ETHER_VLAN;
+		p_index = get_proto_index_using_flag(data->hdr_flags);
+		data->pattern[p_index].spec = &data->vlan;
+		data->pattern[p_index].mask = &rte_flow_item_vlan_mask;
+		data->pattern[p_index].type = RTE_FLOW_ITEM_TYPE_VLAN;
+		break;
+	case ACTION_NVGRE_ENCAP_IPV4_DST:
+	case ACTION_NVGRE_ENCAP_IPV4_SRC:
+	case ACTION_NVGRE_ENCAP_IPV4_PROTO:
+		data = ctx->object;
+		data->hdr_flags |= RTE_PTYPE_L3_IPV4;
+		p_index = get_proto_index_using_flag(data->hdr_flags);
+		data->pattern[p_index].spec = &data->ipv4;
+		data->pattern[p_index].mask = &rte_flow_item_ipv4_mask;
+		data->pattern[p_index].type = RTE_FLOW_ITEM_TYPE_IPV4;
+		break;
+	case ACTION_NVGRE_ENCAP_NVGRE_VSNI:
+		data = ctx->object;
+		data->hdr_flags |= RTE_PTYPE_TUNNEL_NVGRE;
+		p_index = get_proto_index_using_flag(data->hdr_flags);
+		data->pattern[p_index].spec = &data->nvgre;
+		data->pattern[p_index].mask = &rte_flow_item_nvgre_mask;
+		data->pattern[p_index].type = RTE_FLOW_ITEM_TYPE_NVGRE;
+		break;
+	default:
+		return -1;
+	}
+
+	return len;
+}
+
+/** Parse NVGRE_ENCAP action pattern fields value. */
+static int __rte_unused
+parse_vc_action_nvgre_encap_fields_value(struct context *ctx,
+					 const struct token *token,
+					 const char *str, unsigned int len,
+					 void *buf, unsigned int size)
+{
+	struct action_nvgre_encap_data *data;
+	struct ether_addr mac;
+	char str2[len + 1];
+	struct in_addr ip4;
+	uint16_t val1;
+	uint32_t val2;
+	int ret;
+
+	(void)token;
+	(void)buf;
+	if (!ctx->object)
+		return len;
+	data = ctx->object;
+	switch (ctx->curr) {
+	case ACTION_NVGRE_ENCAP_ETH_DST_VALUE:
+		ret = cmdline_parse_etheraddr(NULL, str, &mac, size);
+		if (ret < 0 || (unsigned int)ret != len)
+			return -1;
+		memcpy(&data->eth.dst, &mac, sizeof(mac));
+		break;
+	case ACTION_NVGRE_ENCAP_ETH_SRC_VALUE:
+		ret = cmdline_parse_etheraddr(NULL, str, &mac, size);
+		if (ret < 0 || (unsigned int)ret != len)
+			return -1;
+		memcpy(&data->eth.src, &mac, sizeof(mac));
+		break;
+	case ACTION_NVGRE_ENCAP_ETH_TYPE_VALUE:
+		memcpy(str2, str, len);
+		str2[len] = '\0';
+		val1 = strtoul(str2, NULL, 0);
+		if (val1 == 0)
+			return -1;
+		data->eth.type = htons(val1);
+		break;
+	case ACTION_NVGRE_ENCAP_VLAN_TCI_VALUE:
+		memcpy(str2, str, len);
+		str2[len] = '\0';
+		val1 = strtoul(str2, NULL, 0);
+		if (val1 == 0)
+			return -1;
+		data->vlan.tci = htons(val1);
+		break;
+	case ACTION_NVGRE_ENCAP_IPV4_DST_VALUE:
+		memcpy(str2, str, len);
+		str2[len] = '\0';
+		ret = inet_pton(AF_INET, str2, &ip4);
+		if (ret != 1)
+			return -1;
+		memcpy(&data->ipv4.hdr.dst_addr, &ip4, sizeof(ip4));
+		break;
+	case ACTION_NVGRE_ENCAP_IPV4_SRC_VALUE:
+		memcpy(str2, str, len);
+		str2[len] = '\0';
+		ret = inet_pton(AF_INET, str2, &ip4);
+		if (ret != 1)
+			return -1;
+		memcpy(&data->ipv4.hdr.src_addr, &ip4, sizeof(ip4));
+		break;
+	case ACTION_NVGRE_ENCAP_IPV4_PROTO_VALUE:
+		memcpy(str2, str, len);
+		str2[len] = '\0';
+		val1 = strtoul(str2, NULL, 0);
+		if (val1 == 0)
+			return -1;
+		data->ipv4.hdr.next_proto_id = val1;
+		break;
+	case ACTION_NVGRE_ENCAP_NVGRE_VSNI_VALUE:
+		memcpy(str2, str, len);
+		str2[len] = '\0';
+		val2 = strtoul(str2, NULL, 0);
+		if (val2 == 0)
+			return -1;
+		data->nvgre.tni[0] = (uint8_t)((val2 >> 16) & 0xff);
+		data->nvgre.tni[1] = (uint8_t)((val2 >> 8) & 0xff);
+		data->nvgre.tni[2] = (uint8_t)(val2 & 0xff);
+		break;
+	default:
+		return -1;
+	}
+
+	return len;
+}
+
+/** Parse NVGRE_ENCAP action pattern end. */
+static int __rte_unused
+parse_vc_action_nvgre_encap_end(struct context *ctx,
+				const struct token *token,
+				const char *str, unsigned int len,
+				void *buf, unsigned int size)
+{
+	struct action_nvgre_encap_data *data;
+	uint32_t p_index;
+
+	(void)buf;
+	(void)size;
+	/* Token name must match. */
+	if (parse_default(ctx, token, str, len, NULL, 0) < 0)
+		return -1;
+	if (ctx->curr != ACTION_NVGRE_ENCAP_END)
+		return -1;
+	if (!ctx->object)
+		return len;
+	data = ctx->object;
+	p_index = get_proto_index_using_flag(data->hdr_flags);
+	data->pattern[p_index + 1].type = RTE_FLOW_ITEM_TYPE_END;
+
+	return len;
+}
+
 /** Parse tokens for destroy command. */
 static int
 parse_destroy(struct context *ctx, const struct token *token,
-- 
2.7.4

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [dpdk-dev] [PATCH v2 2/2] doc/guides: updated testpmd app user guide for vxlan/nvgre encap/decap
  2018-05-11 17:13 [dpdk-dev] [PATCH v2 0/2] Added vxlan/nvgre encap/decap support to testpmd Mohammad Abdul Awal
  2018-05-11 17:14 ` [dpdk-dev] [PATCH v2 1/2] app/testpmd: enabled vxlan and nvgre encap/decap support for rte_flow Mohammad Abdul Awal
@ 2018-05-11 17:14 ` Mohammad Abdul Awal
  2018-05-14 10:35   ` Iremonger, Bernard
  1 sibling, 1 reply; 9+ messages in thread
From: Mohammad Abdul Awal @ 2018-05-11 17:14 UTC (permalink / raw)
  To: dev, bernard.iremonger, adrien.mazarguil

Updated the testpmd user guide documentation with how to used new action
types RTE_FLOW_ACTION_VXLAN_ENCAP, RTE_FLOW_ACTION_VXLAN_DECAP,
RTE_FLOW_ACTION_NVGRE_ENCAP, RTE_FLOW_ACTION_NVGRE_DECAP capabilities.

Signed-off-by: Mohammad Abdul Awal <mohammad.abdul.awal@intel.com>
---
 doc/guides/testpmd_app_ug/testpmd_funcs.rst | 50 +++++++++++++++++++++++++++++
 1 file changed, 50 insertions(+)

diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
index 542c217..6ee3ff3 100644
--- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
+++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
@@ -3559,6 +3559,56 @@ This section lists supported actions and their attributes, if any.
 
   - ``ethertype``: Ethertype.
 
+- ``vxlan_encap``: encapsulate the inner flow with pattern of headers
+  according to RFC7348.
+
+  - ``eth_dst {MAC-48}``: outer ether destination.
+
+  - ``eth_src {MAC-48}``: outer ether source.
+
+  - ``eth_type {unsigned}``: outer ether type.
+
+  - ``vlan_tci {unsigned}``: outer vlan tci.
+
+  - ``ipv4_dst {ipv4 address}``: outer ipv4 destination.
+
+  - ``ipv4_src {ipv4 address}``: outer ipv4 source.
+
+  - ``ipv4_proto {unsigned}``: outer ipv4 proto.
+
+  - ``udp_dst {unsigned}``: outer udp destination.
+
+  - ``udp_src {unsigned}``: outer udp source.
+
+  - ``vxlan_vni {unsigned}``: outer vxlan vni.
+
+  - ``end``: outer vxlan header pattern end.
+
+- ``vxlan_decap``: decapsulate the vxlan tunnel flow according to RFC7348.
+
+- ``nvgre_encap``: encapsulate the inner flow with pattern of headers
+  according to RFC7637.
+
+  - ``eth_dst {MAC-48}``: outer ether destination.
+
+  - ``eth_src {MAC-48}``: outer ether source.
+
+  - ``eth_type {unsigned}``: outer ether type.
+
+  - ``vlan_tci {unsigned}``: outer vlan tci.
+
+  - ``ipv4_dst {ipv4 address}``: outer ipv4 destination.
+
+  - ``ipv4_src {ipv4 address}``: outer ipv4 source.
+
+  - ``ipv4_proto {unsigned}``: outer ipv4 proto.
+
+  - ``nvgre_vsni {unsigned}``: outer nvgre vsni.
+
+  - ``end``: outer nvgre header pattern end.
+
+- ``nvgre_decap``: decapsulate the nvgre tunnel flow according to RFC7637.
+
 Destroying flow rules
 ~~~~~~~~~~~~~~~~~~~~~
 
-- 
2.7.4

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [dpdk-dev] [PATCH v2 2/2] doc/guides: updated testpmd app user guide for vxlan/nvgre encap/decap
  2018-05-11 17:14 ` [dpdk-dev] [PATCH v2 2/2] doc/guides: updated testpmd app user guide for vxlan/nvgre encap/decap Mohammad Abdul Awal
@ 2018-05-14 10:35   ` Iremonger, Bernard
  2018-05-14 15:42     ` Mohammad Abdul Awal
  0 siblings, 1 reply; 9+ messages in thread
From: Iremonger, Bernard @ 2018-05-14 10:35 UTC (permalink / raw)
  To: Awal, Mohammad Abdul, dev, adrien.mazarguil; +Cc: Iremonger, Bernard

Hi Awal,

> -----Original Message-----
> From: Awal, Mohammad Abdul
> Sent: Friday, May 11, 2018 6:14 PM
> To: dev@dpdk.org; Iremonger, Bernard <bernard.iremonger@intel.com>;
> adrien.mazarguil@6wind.com
> Subject: [PATCH v2 2/2] doc/guides: updated testpmd app user guide for
> vxlan/nvgre encap/decap
> 
> Updated the testpmd user guide documentation with how to used new action

Typo, "used" in line above should be "use".

> types RTE_FLOW_ACTION_VXLAN_ENCAP, RTE_FLOW_ACTION_VXLAN_DECAP,
> RTE_FLOW_ACTION_NVGRE_ENCAP, RTE_FLOW_ACTION_NVGRE_DECAP
> capabilities.
> 
> Signed-off-by: Mohammad Abdul Awal <mohammad.abdul.awal@intel.com>
> ---
>  doc/guides/testpmd_app_ug/testpmd_funcs.rst | 50
> +++++++++++++++++++++++++++++
>  1 file changed, 50 insertions(+)
> 
> diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
> b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
> index 542c217..6ee3ff3 100644
> --- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
> +++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
> @@ -3559,6 +3559,56 @@ This section lists supported actions and their
> attributes, if any.
> 
>    - ``ethertype``: Ethertype.
> 
> +- ``vxlan_encap``: encapsulate the inner flow with pattern of headers
> +  according to RFC7348.
> +
> +  - ``eth_dst {MAC-48}``: outer ether destination.
> +
> +  - ``eth_src {MAC-48}``: outer ether source.
> +
> +  - ``eth_type {unsigned}``: outer ether type.
> +
> +  - ``vlan_tci {unsigned}``: outer vlan tci.
> +
> +  - ``ipv4_dst {ipv4 address}``: outer ipv4 destination.
> +
> +  - ``ipv4_src {ipv4 address}``: outer ipv4 source.
> +
> +  - ``ipv4_proto {unsigned}``: outer ipv4 proto.
> +
> +  - ``udp_dst {unsigned}``: outer udp destination.
> +
> +  - ``udp_src {unsigned}``: outer udp source.
> +
> +  - ``vxlan_vni {unsigned}``: outer vxlan vni.
> +
> +  - ``end``: outer vxlan header pattern end.
> +
> +- ``vxlan_decap``: decapsulate the vxlan tunnel flow according to RFC7348.
> +
> +- ``nvgre_encap``: encapsulate the inner flow with pattern of headers
> +  according to RFC7637.
> +
> +  - ``eth_dst {MAC-48}``: outer ether destination.
> +
> +  - ``eth_src {MAC-48}``: outer ether source.
> +
> +  - ``eth_type {unsigned}``: outer ether type.
> +
> +  - ``vlan_tci {unsigned}``: outer vlan tci.
> +
> +  - ``ipv4_dst {ipv4 address}``: outer ipv4 destination.
> +
> +  - ``ipv4_src {ipv4 address}``: outer ipv4 source.
> +
> +  - ``ipv4_proto {unsigned}``: outer ipv4 proto.
> +
> +  - ``nvgre_vsni {unsigned}``: outer nvgre vsni.
> +
> +  - ``end``: outer nvgre header pattern end.
> +
> +- ``nvgre_decap``: decapsulate the nvgre tunnel flow according to RFC7637.
> +
>  Destroying flow rules
>  ~~~~~~~~~~~~~~~~~~~~~

I see that section 4.14.1 has been updated to document the syntax of the encap and decap actions, which look fine. 
However my comment on the v1 patch about adding some sample encap and decap rules has not been addressed.
My understanding is, that it is a two stage process where the tunnel endpoint flow is created first and the encapsulated flow is then created, this is not obvious from the syntax description section.
I think it would be useful to add some sample flows after section 4.12.8
> 
> --
> 2.7.4

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [dpdk-dev] [PATCH v2 1/2] app/testpmd: enabled vxlan and nvgre encap/decap support for rte_flow
  2018-05-11 17:14 ` [dpdk-dev] [PATCH v2 1/2] app/testpmd: enabled vxlan and nvgre encap/decap support for rte_flow Mohammad Abdul Awal
@ 2018-05-14 11:14   ` Iremonger, Bernard
  0 siblings, 0 replies; 9+ messages in thread
From: Iremonger, Bernard @ 2018-05-14 11:14 UTC (permalink / raw)
  To: Awal, Mohammad Abdul, dev, adrien.mazarguil; +Cc: Iremonger, Bernard

Hi Awal,

> -----Original Message-----
> From: Awal, Mohammad Abdul
> Sent: Friday, May 11, 2018 6:14 PM
> To: dev@dpdk.org; Iremonger, Bernard <bernard.iremonger@intel.com>;
> adrien.mazarguil@6wind.com
> Subject: [PATCH v2 1/2] app/testpmd: enabled vxlan and nvgre encap/decap
> support for rte_flow
> 
> We have enabled testpmd application with ability to create a flow with
> vxlan/nvgre tunnel types and with encapsulation/decapsulation functionalities.
> 
> Signed-off-by: Mohammad Abdul Awal <mohammad.abdul.awal@intel.com>
> ---
>  app/test-pmd/cmdline_flow.c | 937
> ++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 937 insertions(+)
> 
> diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c index
> 5754e78..5ffc127 100644
> --- a/app/test-pmd/cmdline_flow.c
> +++ b/app/test-pmd/cmdline_flow.c
> @@ -237,6 +237,48 @@ enum index {
>  	ACTION_OF_POP_MPLS_ETHERTYPE,
>  	ACTION_OF_PUSH_MPLS,
>  	ACTION_OF_PUSH_MPLS_ETHERTYPE,
> +	ACTION_VXLAN_ENCAP,
> +	ACTION_VXLAN_ENCAP_ETH_DST,
> +	ACTION_VXLAN_ENCAP_ETH_DST_VALUE,
> +	ACTION_VXLAN_ENCAP_ETH_SRC,
> +	ACTION_VXLAN_ENCAP_ETH_SRC_VALUE,
> +	ACTION_VXLAN_ENCAP_ETH_TYPE,
> +	ACTION_VXLAN_ENCAP_ETH_TYPE_VALUE,
> +	ACTION_VXLAN_ENCAP_VLAN_TCI,
> +	ACTION_VXLAN_ENCAP_VLAN_TCI_VALUE,
> +	ACTION_VXLAN_ENCAP_IPV4_DST,
> +	ACTION_VXLAN_ENCAP_IPV4_DST_VALUE,
> +	ACTION_VXLAN_ENCAP_IPV4_SRC,
> +	ACTION_VXLAN_ENCAP_IPV4_SRC_VALUE,
> +	ACTION_VXLAN_ENCAP_IPV4_PROTO,
> +	ACTION_VXLAN_ENCAP_IPV4_PROTO_VALUE,
> +	ACTION_VXLAN_ENCAP_UDP_SRC,
> +	ACTION_VXLAN_ENCAP_UDP_SRC_VALUE,
> +	ACTION_VXLAN_ENCAP_UDP_DST,
> +	ACTION_VXLAN_ENCAP_UDP_DST_VALUE,
> +	ACTION_VXLAN_ENCAP_VXLAN_VNI,
> +	ACTION_VXLAN_ENCAP_VXLAN_VNI_VALUE,
> +	ACTION_VXLAN_ENCAP_END,
> +	ACTION_VXLAN_DECAP,
> +	ACTION_NVGRE_ENCAP,
> +	ACTION_NVGRE_ENCAP_ETH_DST,
> +	ACTION_NVGRE_ENCAP_ETH_DST_VALUE,
> +	ACTION_NVGRE_ENCAP_ETH_SRC,
> +	ACTION_NVGRE_ENCAP_ETH_SRC_VALUE,
> +	ACTION_NVGRE_ENCAP_ETH_TYPE,
> +	ACTION_NVGRE_ENCAP_ETH_TYPE_VALUE,
> +	ACTION_NVGRE_ENCAP_VLAN_TCI,
> +	ACTION_NVGRE_ENCAP_VLAN_TCI_VALUE,
> +	ACTION_NVGRE_ENCAP_IPV4_DST,
> +	ACTION_NVGRE_ENCAP_IPV4_DST_VALUE,
> +	ACTION_NVGRE_ENCAP_IPV4_SRC,
> +	ACTION_NVGRE_ENCAP_IPV4_SRC_VALUE,
> +	ACTION_NVGRE_ENCAP_IPV4_PROTO,
> +	ACTION_NVGRE_ENCAP_IPV4_PROTO_VALUE,
> +	ACTION_NVGRE_ENCAP_NVGRE_VSNI,
> +	ACTION_NVGRE_ENCAP_NVGRE_VSNI_VALUE,
> +	ACTION_NVGRE_ENCAP_END,
> +	ACTION_NVGRE_DECAP,
>  };
> 
>  /** Maximum size for pattern in struct rte_flow_item_raw. */ @@ -256,6
> +298,30 @@ struct action_rss_data {
>  	uint16_t queue[ACTION_RSS_QUEUE_NUM];
>  };
> 
> +#define ACTION_VXLAN_ENCAP_MAX_PATTERN 5 #define
> +ACTION_NVGRE_ENCAP_MAX_PATTERN 4
> +
> +struct action_vxlan_encap_data {
> +	struct rte_flow_action_vxlan_encap conf;
> +	struct rte_flow_item pattern[ACTION_VXLAN_ENCAP_MAX_PATTERN];
> +	struct rte_flow_item_eth eth;
> +	struct rte_flow_item_vlan vlan;
> +	struct rte_flow_item_ipv4 ipv4;
> +	struct rte_flow_item_udp udp;
> +	struct rte_flow_item_vxlan vxlan;
> +	uint32_t hdr_flags;
> +};
> +
> +struct action_nvgre_encap_data {
> +	struct rte_flow_action_nvgre_encap conf;
> +	struct rte_flow_item pattern[ACTION_NVGRE_ENCAP_MAX_PATTERN];
> +	struct rte_flow_item_eth eth;
> +	struct rte_flow_item_vlan vlan;
> +	struct rte_flow_item_ipv4 ipv4;
> +	struct rte_flow_item_nvgre nvgre;
> +	uint32_t hdr_flags;
> +};
> +
>  /** Maximum number of subsequent tokens and arguments on the stack. */
> #define CTX_STACK_SIZE 16
> 
> @@ -383,6 +449,13 @@ struct token {
>  		.size = (s), \
>  	})
> 
> +#define ARGS_ENTRY_ARB_HTON(o, s) \
> +	(&(const struct arg){ \
> +		.hton = 1, \
> +		.offset = (o), \
> +		.size = (s), \
> +	})
> +

The ARGS_ENTRY_ARB_HTON macro does not seem to be used in the code.
Should it be removed?

>  /** Same as ARGS_ENTRY_ARB() with bounded values. */  #define
> ARGS_ENTRY_ARB_BOUNDED(o, s, i, a) \
>  	(&(const struct arg){ \
> @@ -773,6 +846,10 @@ static const enum index next_action[] = {
>  	ACTION_OF_SET_VLAN_PCP,
>  	ACTION_OF_POP_MPLS,
>  	ACTION_OF_PUSH_MPLS,
> +	ACTION_VXLAN_ENCAP,
> +	ACTION_VXLAN_DECAP,
> +	ACTION_NVGRE_ENCAP,
> +	ACTION_NVGRE_DECAP,
>  	ZERO,
>  };
> 
> @@ -874,6 +951,46 @@ static const enum index action_jump[] = {
>  	ZERO,
>  };
> 
> +static const enum index action_vxlan_encap[] = {
> +	ACTION_VXLAN_ENCAP_ETH_DST,
> +	ACTION_VXLAN_ENCAP_ETH_SRC,
> +	ACTION_VXLAN_ENCAP_ETH_TYPE,
> +	ACTION_VXLAN_ENCAP_VLAN_TCI,
> +	ACTION_VXLAN_ENCAP_IPV4_DST,
> +	ACTION_VXLAN_ENCAP_IPV4_SRC,
> +	ACTION_VXLAN_ENCAP_IPV4_PROTO,
> +	ACTION_VXLAN_ENCAP_UDP_DST,
> +	ACTION_VXLAN_ENCAP_UDP_SRC,
> +	ACTION_VXLAN_ENCAP_VXLAN_VNI,
> +	ACTION_VXLAN_ENCAP_END,
> +	ACTION_NEXT,
> +	ZERO,
> +};
> +
> +static const enum index action_vxlan_decap[] = {
> +	ACTION_NEXT,
> +	ZERO,
> +};
> +
> +static const enum index action_nvgre_encap[] = {
> +	ACTION_NVGRE_ENCAP_ETH_DST,
> +	ACTION_NVGRE_ENCAP_ETH_SRC,
> +	ACTION_NVGRE_ENCAP_ETH_TYPE,
> +	ACTION_NVGRE_ENCAP_VLAN_TCI,
> +	ACTION_NVGRE_ENCAP_IPV4_DST,
> +	ACTION_NVGRE_ENCAP_IPV4_SRC,
> +	ACTION_NVGRE_ENCAP_IPV4_PROTO,
> +	ACTION_NVGRE_ENCAP_NVGRE_VSNI,
> +	ACTION_NVGRE_ENCAP_END,
> +	ACTION_NEXT,
> +	ZERO,
> +};
> +
> +static const enum index action_nvgre_decap[] = {
> +	ACTION_NEXT,
> +	ZERO,
> +};
> +
>  static int parse_init(struct context *, const struct token *,
>  		      const char *, unsigned int,
>  		      void *, unsigned int);
> @@ -896,6 +1013,42 @@ static int parse_vc_action_rss_type(struct context *,
> const struct token *,  static int parse_vc_action_rss_queue(struct context *,
> const struct token *,
>  				     const char *, unsigned int, void *,
>  				     unsigned int);
> +static int parse_vc_action_vxlan_encap(struct context *, const struct token *,
> +				       const char *, unsigned int, void *,
> +				       unsigned int);
> +static int parse_vc_action_vxlan_decap(struct context *, const struct token *,
> +				       const char *, unsigned int, void *,
> +				       unsigned int);
> +static int parse_vc_action_vxlan_encap_fields(struct context *,
> +					      const struct token *,
> +					      const char *, unsigned int,
> +					      void *, unsigned int);
> +static int parse_vc_action_vxlan_encap_fields_value(struct context *,
> +						    const struct token *,
> +						    const char *, unsigned int,
> +						    void *, unsigned int);
> +static int parse_vc_action_vxlan_encap_end(struct context *,
> +					   const struct token *,
> +					   const char *, unsigned int,
> +					   void *, unsigned int);
> +static int parse_vc_action_nvgre_encap(struct context *, const struct token *,
> +				       const char *, unsigned int, void *,
> +				       unsigned int);
> +static int parse_vc_action_nvgre_decap(struct context *, const struct token *,
> +				       const char *, unsigned int, void *,
> +				       unsigned int);
> +static int parse_vc_action_nvgre_encap_fields(struct context *,
> +					      const struct token *,
> +					      const char *, unsigned int,
> +					      void *, unsigned int);
> +static int parse_vc_action_nvgre_encap_fields_value(struct context *,
> +						    const struct token *,
> +						    const char *, unsigned int,
> +						    void *, unsigned int);
> +static int parse_vc_action_nvgre_encap_end(struct context *,
> +					   const struct token *,
> +					   const char *, unsigned int,
> +					   void *, unsigned int);
>  static int parse_destroy(struct context *, const struct token *,
>  			 const char *, unsigned int,
>  			 void *, unsigned int);
> @@ -2362,6 +2515,282 @@ static const struct token token_list[] = {
>  			      ethertype)),
>  		.call = parse_vc_conf,
>  	},
> +	[ACTION_VXLAN_ENCAP] = {
> +		.name = "vxlan_encap",
> +		.help = "encap flow with vxlan tunnel definition",
> +		.priv = PRIV_ACTION(VXLAN_ENCAP,
> +				    sizeof(struct action_vxlan_encap_data)),
> +		.next = NEXT(action_vxlan_encap,
> +
> 	NEXT_ENTRY(ACTION_VXLAN_ENCAP_ETH_DST,
> +					ACTION_VXLAN_ENCAP_ETH_SRC,
> +					ACTION_VXLAN_ENCAP_ETH_TYPE,
> +					ACTION_VXLAN_ENCAP_VLAN_TCI,
> +					ACTION_VXLAN_ENCAP_IPV4_DST,
> +					ACTION_VXLAN_ENCAP_IPV4_SRC,
> +					ACTION_VXLAN_ENCAP_IPV4_PROTO,
> +					ACTION_VXLAN_ENCAP_UDP_DST,
> +					ACTION_VXLAN_ENCAP_UDP_SRC,
> +					ACTION_VXLAN_ENCAP_VXLAN_VNI,
> +					ACTION_VXLAN_ENCAP_END)),
> +		.call = parse_vc_action_vxlan_encap,
> +	},
> +	[ACTION_VXLAN_DECAP] = {
> +		.name = "vxlan_decap",
> +		.help = "decap flow with vxlan tunnel definition",
> +		.priv = PRIV_ACTION(VXLAN_DECAP, 0),
> +		.next = NEXT(action_vxlan_decap),
> +		.call = parse_vc_action_vxlan_decap,
> +	},
> +	[ACTION_VXLAN_ENCAP_ETH_DST] = {
> +		.name = "eth_dst",
> +		.help = "destination MAC for vxlan tunnel",
> +		.next = NEXT(action_vxlan_encap,
> +
> NEXT_ENTRY(ACTION_VXLAN_ENCAP_ETH_DST_VALUE)),
> +		.call = parse_vc_action_vxlan_encap_fields,
> +	},
> +	[ACTION_VXLAN_ENCAP_ETH_DST_VALUE] = {
> +		.name = "eth_dst_value",
> +		.help = "destination MAC for vxlan tunnel",
> +		.call = parse_vc_action_vxlan_encap_fields_value,
> +	},
> +	[ACTION_VXLAN_ENCAP_ETH_SRC] = {
> +		.name = "eth_src",
> +		.help = "source MAC for vxlan tunnel",
> +		.next = NEXT(action_vxlan_encap,
> +
> NEXT_ENTRY(ACTION_VXLAN_ENCAP_ETH_SRC_VALUE)),
> +		.call = parse_vc_action_vxlan_encap_fields,
> +	},
> +	[ACTION_VXLAN_ENCAP_ETH_SRC_VALUE] = {
> +		.name = "eth_src_value",
> +		.help = "source MAC for vxlan tunnel",
> +		.call = parse_vc_action_vxlan_encap_fields_value,
> +	},
> +	[ACTION_VXLAN_ENCAP_ETH_TYPE] = {
> +		.name = "eth_type",
> +		.help = "eth type for vxlan tunnel",
> +		.next = NEXT(action_vxlan_encap,
> +
> NEXT_ENTRY(ACTION_VXLAN_ENCAP_ETH_TYPE_VALUE)),
> +		.call = parse_vc_action_vxlan_encap_fields,
> +	},
> +	[ACTION_VXLAN_ENCAP_ETH_TYPE_VALUE] = {
> +		.name = "eth_type_value",
> +		.help = "eth type for vxlan tunnel",
> +		.call = parse_vc_action_vxlan_encap_fields_value,
> +	},
> +	[ACTION_VXLAN_ENCAP_VLAN_TCI] = {
> +		.name = "vlan_tci",
> +		.help = "vlan tci for vxlan tunnel",
> +		.next = NEXT(action_vxlan_encap,
> +
> NEXT_ENTRY(ACTION_VXLAN_ENCAP_VLAN_TCI_VALUE)),
> +		.call = parse_vc_action_vxlan_encap_fields,
> +	},
> +	[ACTION_VXLAN_ENCAP_VLAN_TCI_VALUE] = {
> +		.name = "vlan_tci_value",
> +		.help = "vlan tci for vxlan tunnel",
> +		.call = parse_vc_action_vxlan_encap_fields_value,
> +	},
> +	[ACTION_VXLAN_ENCAP_IPV4_DST] = {
> +		.name = "ipv4_dst",
> +		.help = "destination ipv4 IP for vxlan tunnel",
> +		.next = NEXT(action_vxlan_encap,
> +
> NEXT_ENTRY(ACTION_VXLAN_ENCAP_IPV4_DST_VALUE)),
> +		.call = parse_vc_action_vxlan_encap_fields,
> +	},
> +	[ACTION_VXLAN_ENCAP_IPV4_DST_VALUE] = {
> +		.name = "ipv4_dst_value",
> +		.help = "destination ipv4 IP for vxlan tunnel",
> +		.call = parse_vc_action_vxlan_encap_fields_value,
> +	},
> +	[ACTION_VXLAN_ENCAP_IPV4_SRC] = {
> +		.name = "ipv4_src",
> +		.help = "source ipv4 IP for vxlan tunnel",
> +		.next = NEXT(action_vxlan_encap,
> +
> NEXT_ENTRY(ACTION_VXLAN_ENCAP_IPV4_SRC_VALUE)),
> +		.call = parse_vc_action_vxlan_encap_fields,
> +	},
> +	[ACTION_VXLAN_ENCAP_IPV4_SRC_VALUE] = {
> +		.name = "ipv4_src_value",
> +		.help = "source ipv4 IP for vxlan tunnel",
> +		.call = parse_vc_action_vxlan_encap_fields_value,
> +	},
> +	[ACTION_VXLAN_ENCAP_IPV4_PROTO] = {
> +		.name = "ipv4_proto",
> +		.help = "ipv4 proto for vxlan tunnel",
> +		.next = NEXT(action_vxlan_encap,
> +
> NEXT_ENTRY(ACTION_VXLAN_ENCAP_IPV4_PROTO_VALUE)),
> +		.call = parse_vc_action_vxlan_encap_fields,
> +	},
> +	[ACTION_VXLAN_ENCAP_IPV4_PROTO_VALUE] = {
> +		.name = "ipv4_proto_value",
> +		.help = "ipv4 proto for vxlan tunnel",
> +		.call = parse_vc_action_vxlan_encap_fields_value,
> +	},
> +	[ACTION_VXLAN_ENCAP_UDP_DST] = {
> +		.name = "udp_dst",
> +		.help = "udp destination port for vxlan tunnel",
> +		.next = NEXT(action_vxlan_encap,
> +
> NEXT_ENTRY(ACTION_VXLAN_ENCAP_UDP_DST_VALUE)),
> +		.call = parse_vc_action_vxlan_encap_fields,
> +	},
> +	[ACTION_VXLAN_ENCAP_UDP_DST_VALUE] = {
> +		.name = "udp_dst_value",
> +		.help = "udp destination port for vxlan tunnel",
> +		.call = parse_vc_action_vxlan_encap_fields_value,
> +	},
> +	[ACTION_VXLAN_ENCAP_UDP_SRC] = {
> +		.name = "udp_src",
> +		.help = "udp source port for vxlan tunnel",
> +		.next = NEXT(action_vxlan_encap,
> +
> NEXT_ENTRY(ACTION_VXLAN_ENCAP_UDP_SRC_VALUE)),
> +		.call = parse_vc_action_vxlan_encap_fields,
> +	},
> +	[ACTION_VXLAN_ENCAP_UDP_SRC_VALUE] = {
> +		.name = "udp_src_value",
> +		.help = "udp source port for vxlan tunnel",
> +		.call = parse_vc_action_vxlan_encap_fields_value,
> +	},
> +	[ACTION_VXLAN_ENCAP_VXLAN_VNI] = {
> +		.name = "vxlan_vni",
> +		.help = "vxlan vni for vxlan tunnel",
> +		.next = NEXT(action_vxlan_encap,
> +
> NEXT_ENTRY(ACTION_VXLAN_ENCAP_VXLAN_VNI_VALUE)),
> +		.call = parse_vc_action_vxlan_encap_fields,
> +	},
> +	[ACTION_VXLAN_ENCAP_VXLAN_VNI_VALUE] = {
> +		.name = "vxlan_vni_value",
> +		.help = "vxlan vni for vxlan tunnel",
> +		.call = parse_vc_action_vxlan_encap_fields_value,
> +	},
> +	[ACTION_VXLAN_ENCAP_END] = {
> +		.name = "end",
> +		.help = "end of the pattern for vxlan encap",
> +		.call = parse_vc_action_vxlan_encap_end,
> +	},
> +	[ACTION_NVGRE_ENCAP] = {
> +		.name = "nvgre_encap",
> +		.help = "encap flow with nvgre tunnel definition",
> +		.priv = PRIV_ACTION(NVGRE_ENCAP,
> +				    sizeof(struct action_nvgre_encap_data)),
> +		.next = NEXT(action_nvgre_encap,
> +
> 	NEXT_ENTRY(ACTION_NVGRE_ENCAP_ETH_DST,
> +					ACTION_NVGRE_ENCAP_ETH_SRC,
> +					ACTION_NVGRE_ENCAP_ETH_TYPE,
> +					ACTION_NVGRE_ENCAP_VLAN_TCI,
> +					ACTION_NVGRE_ENCAP_IPV4_DST,
> +					ACTION_NVGRE_ENCAP_IPV4_SRC,
> +					ACTION_NVGRE_ENCAP_IPV4_PROTO,
> +					ACTION_NVGRE_ENCAP_NVGRE_VSNI,
> +					ACTION_NVGRE_ENCAP_END)),
> +		.call = parse_vc_action_nvgre_encap,
> +	},
> +	[ACTION_NVGRE_DECAP] = {
> +		.name = "nvgre_decap",
> +		.help = "decap flow with nvgre tunnel definition",
> +		.priv = PRIV_ACTION(NVGRE_DECAP, 0),
> +		.next = NEXT(action_nvgre_decap),
> +		.call = parse_vc_action_nvgre_decap,
> +	},
> +	[ACTION_NVGRE_ENCAP_ETH_DST] = {
> +		.name = "eth_dst",
> +		.help = "destination MAC for nvgre tunnel",
> +		.next = NEXT(action_nvgre_encap,
> +
> NEXT_ENTRY(ACTION_NVGRE_ENCAP_ETH_DST_VALUE)),
> +		.call = parse_vc_action_nvgre_encap_fields,
> +	},
> +	[ACTION_NVGRE_ENCAP_ETH_DST_VALUE] = {
> +		.name = "eth_dst_value",
> +		.help = "destination MAC for nvgre tunnel",
> +		.call = parse_vc_action_nvgre_encap_fields_value,
> +	},
> +	[ACTION_NVGRE_ENCAP_ETH_SRC] = {
> +		.name = "eth_src",
> +		.help = "source MAC for nvgre tunnel",
> +		.next = NEXT(action_nvgre_encap,
> +
> NEXT_ENTRY(ACTION_NVGRE_ENCAP_ETH_SRC_VALUE)),
> +		.call = parse_vc_action_nvgre_encap_fields,
> +	},
> +	[ACTION_NVGRE_ENCAP_ETH_SRC_VALUE] = {
> +		.name = "eth_src_value",
> +		.help = "source MAC for nvgre tunnel",
> +		.call = parse_vc_action_nvgre_encap_fields_value,
> +	},
> +	[ACTION_NVGRE_ENCAP_ETH_TYPE] = {
> +		.name = "eth_type",
> +		.help = "eth type for nvgre tunnel",
> +		.next = NEXT(action_nvgre_encap,
> +
> NEXT_ENTRY(ACTION_NVGRE_ENCAP_ETH_TYPE_VALUE)),
> +		.call = parse_vc_action_nvgre_encap_fields,
> +	},
> +	[ACTION_NVGRE_ENCAP_ETH_TYPE_VALUE] = {
> +		.name = "eth_type_value",
> +		.help = "eth type for nvgre tunnel",
> +		.call = parse_vc_action_nvgre_encap_fields_value,
> +	},
> +	[ACTION_NVGRE_ENCAP_VLAN_TCI] = {
> +		.name = "vlan_tci",
> +		.help = "vlan tci for nvgre tunnel",
> +		.next = NEXT(action_nvgre_encap,
> +
> NEXT_ENTRY(ACTION_NVGRE_ENCAP_VLAN_TCI_VALUE)),
> +		.call = parse_vc_action_nvgre_encap_fields,
> +	},
> +	[ACTION_NVGRE_ENCAP_VLAN_TCI_VALUE] = {
> +		.name = "vlan_tci_value",
> +		.help = "vlan tci for nvgre tunnel",
> +		.call = parse_vc_action_nvgre_encap_fields_value,
> +	},
> +	[ACTION_NVGRE_ENCAP_IPV4_DST] = {
> +		.name = "ipv4_dst",
> +		.help = "destination ipv4 IP for nvgre tunnel",
> +		.next = NEXT(action_nvgre_encap,
> +
> NEXT_ENTRY(ACTION_NVGRE_ENCAP_IPV4_DST_VALUE)),
> +		.call = parse_vc_action_nvgre_encap_fields,
> +	},
> +	[ACTION_NVGRE_ENCAP_IPV4_DST_VALUE] = {
> +		.name = "ipv4_dst_value",
> +		.help = "destination ipv4 IP for nvgre tunnel",
> +		.call = parse_vc_action_nvgre_encap_fields_value,
> +	},
> +	[ACTION_NVGRE_ENCAP_IPV4_SRC] = {
> +		.name = "ipv4_src",
> +		.help = "source ipv4 IP for nvgre tunnel",
> +		.next = NEXT(action_nvgre_encap,
> +
> NEXT_ENTRY(ACTION_NVGRE_ENCAP_IPV4_SRC_VALUE)),
> +		.call = parse_vc_action_nvgre_encap_fields,
> +	},
> +	[ACTION_NVGRE_ENCAP_IPV4_SRC_VALUE] = {
> +		.name = "ipv4_src_value",
> +		.help = "source ipv4 IP for nvgre tunnel",
> +		.call = parse_vc_action_nvgre_encap_fields_value,
> +	},
> +	[ACTION_NVGRE_ENCAP_IPV4_PROTO] = {
> +		.name = "ipv4_proto",
> +		.help = "ipv4 proto for nvgre tunnel",
> +		.next = NEXT(action_nvgre_encap,
> +
> NEXT_ENTRY(ACTION_NVGRE_ENCAP_IPV4_PROTO_VALUE)),
> +		.call = parse_vc_action_nvgre_encap_fields,
> +	},
> +	[ACTION_NVGRE_ENCAP_IPV4_PROTO_VALUE] = {
> +		.name = "ipv4_proto_value",
> +		.help = "ipv4 proto for nvgre tunnel",
> +		.call = parse_vc_action_nvgre_encap_fields_value,
> +	},
> +	[ACTION_NVGRE_ENCAP_NVGRE_VSNI] = {
> +		.name = "nvgre_vsni",
> +		.help = "nvgre vsni for NVGRE tunnel",
> +		.next = NEXT(action_nvgre_encap,
> +
> NEXT_ENTRY(ACTION_NVGRE_ENCAP_NVGRE_VSNI_VALUE)),
> +		.call = parse_vc_action_nvgre_encap_fields,
> +	},
> +	[ACTION_NVGRE_ENCAP_NVGRE_VSNI_VALUE] = {
> +		.name = "nvgre_vsni_value",
> +		.help = "nvgre vsni for nvgre tunnel",
> +		.call = parse_vc_action_nvgre_encap_fields_value,
> +	},
> +	[ACTION_NVGRE_ENCAP_END] = {
> +		.name = "end",
> +		.help = "end of the pattern for nvgre encap",
> +		.call = parse_vc_action_nvgre_encap_end,
> +	},
>  };
> 
>  /** Remove and return last entry from argument stack. */ @@ -2924,6
> +3353,514 @@ parse_vc_action_rss_queue(struct context *ctx, const struct
> token *token,
>  	return len;
>  }
> 
> +/** Parse VXLAN_ENCAP action. */
> +static int __rte_unused
> +parse_vc_action_vxlan_encap(struct context *ctx, const struct token *token,
> +			    const char *str, unsigned int len,
> +			    void *buf, unsigned int size)
> +{
> +	struct buffer *out = buf;
> +	struct rte_flow_action *action;
> +	struct action_vxlan_encap_data *data;
> +	int ret;
> +
> +	ret = parse_vc(ctx, token, str, len, buf, size);
> +	if (ret < 0)
> +		return ret;
> +	/* Nothing else to do if there is no buffer. */
> +	if (!out)
> +		return ret;
> +	if (!out->args.vc.actions_n)
> +		return -1;
> +	action = &out->args.vc.actions[out->args.vc.actions_n - 1];
> +	/* Point to selected object. */
> +	ctx->object = out->args.vc.data;
> +	ctx->objmask = NULL;
> +	/* Set up default configuration. */
> +	data = ctx->object;
> +	data->conf.definition = data->pattern;
> +	action->conf = &data->conf;
> +
> +	return ret;
> +}
> +
> +/** Parse VXLAN_DECAP action. */
> +static int
> +parse_vc_action_vxlan_decap(struct context *ctx, const struct token *token,
> +			    const char *str, unsigned int len,
> +			    void *buf, unsigned int size)
> +{
> +	struct buffer *out = buf;
> +	int ret;
> +
> +	ret = parse_vc(ctx, token, str, len, buf, size);
> +	if (ret < 0)
> +		return ret;
> +	/* Nothing else to do if there is no buffer. */
> +	if (!out)
> +		return ret;
> +	if (!out->args.vc.actions_n)
> +		return -1;
> +	/* Point to selected object. */
> +	ctx->object = out->args.vc.data;
> +	ctx->objmask = NULL;
> +	return ret;
> +}
> +
> +static uint32_t get_proto_index_using_flag(uint32_t flag) {
> +	uint32_t c = 0, i = 0;
> +	uint32_t supported_ptypes[] = {
> +					RTE_PTYPE_L2_ETHER,
> +					RTE_PTYPE_L2_ETHER_VLAN,
> +					RTE_PTYPE_L3_IPV4,
> +					RTE_PTYPE_L4_UDP,
> +					RTE_PTYPE_TUNNEL_VXLAN,
> +					RTE_PTYPE_TUNNEL_NVGRE
> +				       };
> +
> +	for (i = 0; i != RTE_DIM(supported_ptypes); i++) {
> +		if (supported_ptypes[i] & flag)
> +			c++;
> +	}
> +	c = (c > 0) ? (c - 1) : 0;
> +
> +	return c;
> +}
> +
> +/** Parse VXLAN_ENCAP action pattern fields. */ static int __rte_unused
> +parse_vc_action_vxlan_encap_fields(struct context *ctx,
> +				   const struct token *token,
> +				   const char *str, unsigned int len,
> +				   void *buf, unsigned int size)
> +{
> +	struct action_vxlan_encap_data *data;
> +	uint32_t p_index;
> +
> +	(void)buf;
> +	(void)size;
> +	/* Token name must match. */
> +	if (parse_default(ctx, token, str, len, NULL, 0) < 0)
> +		return -1;
> +	if (!ctx->object)
> +		return len;
> +	switch (ctx->curr) {
> +	case ACTION_VXLAN_ENCAP_ETH_DST:
> +	case ACTION_VXLAN_ENCAP_ETH_SRC:
> +	case ACTION_VXLAN_ENCAP_ETH_TYPE:
> +		data = ctx->object;
> +		data->hdr_flags |= RTE_PTYPE_L2_ETHER;
> +		p_index = get_proto_index_using_flag(data->hdr_flags);
> +		data->pattern[p_index].spec = &data->eth;
> +		data->pattern[p_index].mask = &rte_flow_item_eth_mask;
> +		data->pattern[p_index].type = RTE_FLOW_ITEM_TYPE_ETH;
> +		break;
> +	case ACTION_VXLAN_ENCAP_VLAN_TCI:
> +		data = ctx->object;
> +		data->hdr_flags |= RTE_PTYPE_L2_ETHER_VLAN;
> +		p_index = get_proto_index_using_flag(data->hdr_flags);
> +		data->pattern[p_index].spec = &data->vlan;
> +		data->pattern[p_index].mask = &rte_flow_item_vlan_mask;
> +		data->pattern[p_index].type = RTE_FLOW_ITEM_TYPE_VLAN;
> +		break;
> +	case ACTION_VXLAN_ENCAP_IPV4_DST:
> +	case ACTION_VXLAN_ENCAP_IPV4_SRC:
> +	case ACTION_VXLAN_ENCAP_IPV4_PROTO:
> +		data = ctx->object;
> +		data->hdr_flags |= RTE_PTYPE_L3_IPV4;
> +		p_index = get_proto_index_using_flag(data->hdr_flags);
> +		data->pattern[p_index].spec = &data->ipv4;
> +		data->pattern[p_index].mask = &rte_flow_item_ipv4_mask;
> +		data->pattern[p_index].type = RTE_FLOW_ITEM_TYPE_IPV4;
> +		break;
> +	case ACTION_VXLAN_ENCAP_UDP_DST:
> +	case ACTION_VXLAN_ENCAP_UDP_SRC:
> +		data = ctx->object;
> +		data->hdr_flags |= RTE_PTYPE_L4_UDP;
> +		p_index = get_proto_index_using_flag(data->hdr_flags);
> +		data->pattern[p_index].spec = &data->udp;
> +		data->pattern[p_index].mask = &rte_flow_item_udp_mask;
> +		data->pattern[p_index].type = RTE_FLOW_ITEM_TYPE_UDP;
> +		break;
> +	case ACTION_VXLAN_ENCAP_VXLAN_VNI:
> +		data = ctx->object;
> +		data->hdr_flags |= RTE_PTYPE_TUNNEL_VXLAN;
> +		p_index = get_proto_index_using_flag(data->hdr_flags);
> +		data->pattern[p_index].spec = &data->vxlan;
> +		data->pattern[p_index].mask = &rte_flow_item_vxlan_mask;
> +		data->pattern[p_index].type = RTE_FLOW_ITEM_TYPE_VXLAN;
> +		break;
> +	default:
> +		return -1;
> +	}
> +
> +	return len;
> +}
> +
> +/** Parse VXLAN_ENCAP action pattern fields value. */ static int
> +__rte_unused parse_vc_action_vxlan_encap_fields_value(struct context
> +*ctx,
> +					 const struct token *token,
> +					 const char *str, unsigned int len,
> +					 void *buf, unsigned int size)
> +{
> +	struct action_vxlan_encap_data *data;
> +	struct ether_addr mac;
> +	char str2[len + 1];
> +	struct in_addr ip4;
> +	uint16_t val1;
> +	uint32_t val2;
> +	int ret;
> +
> +	(void)token;
> +	(void)buf;
> +	if (!ctx->object)
> +		return len;
> +	data = ctx->object;
> +	switch (ctx->curr) {
> +	case ACTION_VXLAN_ENCAP_ETH_DST_VALUE:
> +		ret = cmdline_parse_etheraddr(NULL, str, &mac, size);
> +		if (ret < 0 || (unsigned int)ret != len)
> +			return -1;
> +		memcpy(&data->eth.dst, &mac, sizeof(mac));
> +		break;
> +	case ACTION_VXLAN_ENCAP_ETH_SRC_VALUE:
> +		ret = cmdline_parse_etheraddr(NULL, str, &mac, size);
> +		if (ret < 0 || (unsigned int)ret != len)
> +			return -1;
> +		memcpy(&data->eth.src, &mac, sizeof(mac));
> +		break;
> +	case ACTION_VXLAN_ENCAP_ETH_TYPE_VALUE:
> +		memcpy(str2, str, len);
> +		str2[len] = '\0';
> +		val1 = strtoul(str2, NULL, 0);
> +		if (val1 == 0)
> +			return -1;
> +		data->eth.type = htons(val1);
> +		break;
> +	case ACTION_VXLAN_ENCAP_VLAN_TCI_VALUE:
> +		memcpy(str2, str, len);
> +		str2[len] = '\0';
> +		val1 = strtoul(str2, NULL, 0);
> +		if (val1 == 0)
> +			return -1;
> +		data->vlan.tci = htons(val1);
> +		break;
> +	case ACTION_VXLAN_ENCAP_IPV4_DST_VALUE:
> +		memcpy(str2, str, len);
> +		str2[len] = '\0';
> +		ret = inet_pton(AF_INET, str2, &ip4);
> +		if (ret != 1)
> +			return -1;
> +		memcpy(&data->ipv4.hdr.dst_addr, &ip4, sizeof(ip4));
> +		break;
> +	case ACTION_VXLAN_ENCAP_IPV4_SRC_VALUE:
> +		memcpy(str2, str, len);
> +		str2[len] = '\0';
> +		ret = inet_pton(AF_INET, str2, &ip4);
> +		if (ret != 1)
> +			return -1;
> +		memcpy(&data->ipv4.hdr.src_addr, &ip4, sizeof(ip4));
> +		break;
> +	case ACTION_VXLAN_ENCAP_IPV4_PROTO_VALUE:
> +		memcpy(str2, str, len);
> +		str2[len] = '\0';
> +		val1 = strtoul(str2, NULL, 0);
> +		if (val1 == 0)
> +			return -1;
> +		data->ipv4.hdr.next_proto_id = val1;
> +		break;
> +	case ACTION_VXLAN_ENCAP_UDP_DST_VALUE:
> +		memcpy(str2, str, len);
> +		str2[len] = '\0';
> +		val1 = strtoul(str2, NULL, 0);
> +		if (val1 == 0)
> +			return -1;
> +		data->udp.hdr.dst_port = htons(val1);
> +		break;
> +	case ACTION_VXLAN_ENCAP_UDP_SRC_VALUE:
> +		memcpy(str2, str, len);
> +		str2[len] = '\0';
> +		val1 = strtoul(str2, NULL, 0);
> +		if (val1 == 0)
> +			return -1;
> +		data->udp.hdr.src_port = htons(val1);
> +		break;
> +	case ACTION_VXLAN_ENCAP_VXLAN_VNI_VALUE:
> +		memcpy(str2, str, len);
> +		str2[len] = '\0';
> +		val2 = strtoul(str2, NULL, 0);
> +		if (val2 == 0)
> +			return -1;
> +		data->vxlan.vni[0] = (uint8_t)((val2 >> 16) & 0xff);
> +		data->vxlan.vni[1] = (uint8_t)((val2 >> 8) & 0xff);
> +		data->vxlan.vni[2] = (uint8_t)(val2 & 0xff);
> +		break;
> +	default:
> +		return -1;
> +	}
> +
> +	return len;
> +}
> +
> +/** Parse VXLAN_ENCAP action pattern end. */ static int __rte_unused
> +parse_vc_action_vxlan_encap_end(struct context *ctx,
> +				const struct token *token,
> +				const char *str, unsigned int len,
> +				void *buf, unsigned int size)
> +{
> +	struct action_vxlan_encap_data *data;
> +	uint32_t p_index;
> +
> +	(void)buf;
> +	(void)size;
> +	/* Token name must match. */
> +	if (parse_default(ctx, token, str, len, NULL, 0) < 0)
> +		return -1;
> +	if (ctx->curr != ACTION_VXLAN_ENCAP_END)
> +		return -1;
> +	if (!ctx->object)
> +		return len;
> +	data = ctx->object;
> +	p_index = get_proto_index_using_flag(data->hdr_flags);
> +	data->pattern[p_index + 1].type = RTE_FLOW_ITEM_TYPE_END;
> +
> +	return len;
> +}
> +
> +/** Parse NVGRE_ENCAP action. */
> +static int __rte_unused
> +parse_vc_action_nvgre_encap(struct context *ctx, const struct token *token,
> +			    const char *str, unsigned int len,
> +			    void *buf, unsigned int size)
> +{
> +	struct buffer *out = buf;
> +	struct rte_flow_action *action;
> +	struct action_nvgre_encap_data *data;
> +	int ret;
> +
> +	ret = parse_vc(ctx, token, str, len, buf, size);
> +	if (ret < 0)
> +		return ret;
> +	/* Nothing else to do if there is no buffer. */
> +	if (!out)
> +		return ret;
> +	if (!out->args.vc.actions_n)
> +		return -1;
> +	action = &out->args.vc.actions[out->args.vc.actions_n - 1];
> +	/* Point to selected object. */
> +	ctx->object = out->args.vc.data;
> +	ctx->objmask = NULL;
> +	/* Set up default configuration. */
> +	data = ctx->object;
> +	data->conf.definition = data->pattern;
> +	action->conf = &data->conf;
> +
> +	return ret;
> +}
> +
> +/** Parse NVGRE_DECAP action. */
> +static int __rte_unused
> +parse_vc_action_nvgre_decap(struct context *ctx, const struct token *token,
> +		    const char *str, unsigned int len,
> +		    void *buf, unsigned int size)
> +{
> +	struct buffer *out = buf;
> +	int ret;
> +
> +	ret = parse_vc(ctx, token, str, len, buf, size);
> +	if (ret < 0)
> +		return ret;
> +	/* Nothing else to do if there is no buffer. */
> +	if (!out)
> +		return ret;
> +	if (!out->args.vc.actions_n)
> +		return -1;
> +	/* Point to selected object. */
> +	ctx->object = out->args.vc.data;
> +	ctx->objmask = NULL;
> +	return ret;
> +}
> +
> +/** Parse NVGRE_ENCAP action pattern fields. */ static int __rte_unused
> +parse_vc_action_nvgre_encap_fields(struct context *ctx,
> +				   const struct token *token,
> +				   const char *str, unsigned int len,
> +				   void *buf, unsigned int size)
> +{
> +	struct action_nvgre_encap_data *data;
> +	uint32_t p_index;
> +
> +	(void)buf;
> +	(void)size;
> +	/* Token name must match. */
> +	if (parse_default(ctx, token, str, len, NULL, 0) < 0)
> +		return -1;
> +	if (!ctx->object)
> +		return len;
> +	switch (ctx->curr) {
> +	case ACTION_NVGRE_ENCAP_ETH_DST:
> +	case ACTION_NVGRE_ENCAP_ETH_SRC:
> +	case ACTION_NVGRE_ENCAP_ETH_TYPE:
> +		data = ctx->object;
> +		data->hdr_flags |= RTE_PTYPE_L2_ETHER;
> +		p_index = get_proto_index_using_flag(data->hdr_flags);
> +		data->pattern[p_index].spec = &data->eth;
> +		data->pattern[p_index].mask = &rte_flow_item_eth_mask;
> +		data->pattern[p_index].type = RTE_FLOW_ITEM_TYPE_ETH;
> +		break;
> +	case ACTION_NVGRE_ENCAP_VLAN_TCI:
> +		data = ctx->object;
> +		data->hdr_flags |= RTE_PTYPE_L2_ETHER_VLAN;
> +		p_index = get_proto_index_using_flag(data->hdr_flags);
> +		data->pattern[p_index].spec = &data->vlan;
> +		data->pattern[p_index].mask = &rte_flow_item_vlan_mask;
> +		data->pattern[p_index].type = RTE_FLOW_ITEM_TYPE_VLAN;
> +		break;
> +	case ACTION_NVGRE_ENCAP_IPV4_DST:
> +	case ACTION_NVGRE_ENCAP_IPV4_SRC:
> +	case ACTION_NVGRE_ENCAP_IPV4_PROTO:
> +		data = ctx->object;
> +		data->hdr_flags |= RTE_PTYPE_L3_IPV4;
> +		p_index = get_proto_index_using_flag(data->hdr_flags);
> +		data->pattern[p_index].spec = &data->ipv4;
> +		data->pattern[p_index].mask = &rte_flow_item_ipv4_mask;
> +		data->pattern[p_index].type = RTE_FLOW_ITEM_TYPE_IPV4;
> +		break;
> +	case ACTION_NVGRE_ENCAP_NVGRE_VSNI:
> +		data = ctx->object;
> +		data->hdr_flags |= RTE_PTYPE_TUNNEL_NVGRE;
> +		p_index = get_proto_index_using_flag(data->hdr_flags);
> +		data->pattern[p_index].spec = &data->nvgre;
> +		data->pattern[p_index].mask = &rte_flow_item_nvgre_mask;
> +		data->pattern[p_index].type = RTE_FLOW_ITEM_TYPE_NVGRE;
> +		break;
> +	default:
> +		return -1;
> +	}
> +
> +	return len;
> +}
> +
> +/** Parse NVGRE_ENCAP action pattern fields value. */ static int
> +__rte_unused parse_vc_action_nvgre_encap_fields_value(struct context
> +*ctx,
> +					 const struct token *token,
> +					 const char *str, unsigned int len,
> +					 void *buf, unsigned int size)
> +{
> +	struct action_nvgre_encap_data *data;
> +	struct ether_addr mac;
> +	char str2[len + 1];
> +	struct in_addr ip4;
> +	uint16_t val1;
> +	uint32_t val2;
> +	int ret;
> +
> +	(void)token;
> +	(void)buf;
> +	if (!ctx->object)
> +		return len;
> +	data = ctx->object;
> +	switch (ctx->curr) {
> +	case ACTION_NVGRE_ENCAP_ETH_DST_VALUE:
> +		ret = cmdline_parse_etheraddr(NULL, str, &mac, size);
> +		if (ret < 0 || (unsigned int)ret != len)
> +			return -1;
> +		memcpy(&data->eth.dst, &mac, sizeof(mac));
> +		break;
> +	case ACTION_NVGRE_ENCAP_ETH_SRC_VALUE:
> +		ret = cmdline_parse_etheraddr(NULL, str, &mac, size);
> +		if (ret < 0 || (unsigned int)ret != len)
> +			return -1;
> +		memcpy(&data->eth.src, &mac, sizeof(mac));
> +		break;
> +	case ACTION_NVGRE_ENCAP_ETH_TYPE_VALUE:
> +		memcpy(str2, str, len);
> +		str2[len] = '\0';
> +		val1 = strtoul(str2, NULL, 0);
> +		if (val1 == 0)
> +			return -1;
> +		data->eth.type = htons(val1);
> +		break;
> +	case ACTION_NVGRE_ENCAP_VLAN_TCI_VALUE:
> +		memcpy(str2, str, len);
> +		str2[len] = '\0';
> +		val1 = strtoul(str2, NULL, 0);
> +		if (val1 == 0)
> +			return -1;
> +		data->vlan.tci = htons(val1);
> +		break;
> +	case ACTION_NVGRE_ENCAP_IPV4_DST_VALUE:
> +		memcpy(str2, str, len);
> +		str2[len] = '\0';
> +		ret = inet_pton(AF_INET, str2, &ip4);
> +		if (ret != 1)
> +			return -1;
> +		memcpy(&data->ipv4.hdr.dst_addr, &ip4, sizeof(ip4));
> +		break;
> +	case ACTION_NVGRE_ENCAP_IPV4_SRC_VALUE:
> +		memcpy(str2, str, len);
> +		str2[len] = '\0';
> +		ret = inet_pton(AF_INET, str2, &ip4);
> +		if (ret != 1)
> +			return -1;
> +		memcpy(&data->ipv4.hdr.src_addr, &ip4, sizeof(ip4));
> +		break;
> +	case ACTION_NVGRE_ENCAP_IPV4_PROTO_VALUE:
> +		memcpy(str2, str, len);
> +		str2[len] = '\0';
> +		val1 = strtoul(str2, NULL, 0);
> +		if (val1 == 0)
> +			return -1;
> +		data->ipv4.hdr.next_proto_id = val1;
> +		break;
> +	case ACTION_NVGRE_ENCAP_NVGRE_VSNI_VALUE:
> +		memcpy(str2, str, len);
> +		str2[len] = '\0';
> +		val2 = strtoul(str2, NULL, 0);
> +		if (val2 == 0)
> +			return -1;
> +		data->nvgre.tni[0] = (uint8_t)((val2 >> 16) & 0xff);
> +		data->nvgre.tni[1] = (uint8_t)((val2 >> 8) & 0xff);
> +		data->nvgre.tni[2] = (uint8_t)(val2 & 0xff);
> +		break;
> +	default:
> +		return -1;
> +	}
> +
> +	return len;
> +}
> +
> +/** Parse NVGRE_ENCAP action pattern end. */ static int __rte_unused
> +parse_vc_action_nvgre_encap_end(struct context *ctx,
> +				const struct token *token,
> +				const char *str, unsigned int len,
> +				void *buf, unsigned int size)
> +{
> +	struct action_nvgre_encap_data *data;
> +	uint32_t p_index;
> +
> +	(void)buf;
> +	(void)size;
> +	/* Token name must match. */
> +	if (parse_default(ctx, token, str, len, NULL, 0) < 0)
> +		return -1;
> +	if (ctx->curr != ACTION_NVGRE_ENCAP_END)
> +		return -1;
> +	if (!ctx->object)
> +		return len;
> +	data = ctx->object;
> +	p_index = get_proto_index_using_flag(data->hdr_flags);
> +	data->pattern[p_index + 1].type = RTE_FLOW_ITEM_TYPE_END;
> +
> +	return len;
> +}
> +
>  /** Parse tokens for destroy command. */  static int  parse_destroy(struct
> context *ctx, const struct token *token,
> --
> 2.7.4

Regards,

Bernard.

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [dpdk-dev] [PATCH v2 2/2] doc/guides: updated testpmd app user guide for vxlan/nvgre encap/decap
  2018-05-14 10:35   ` Iremonger, Bernard
@ 2018-05-14 15:42     ` Mohammad Abdul Awal
  2018-06-14 17:14       ` Ferruh Yigit
  0 siblings, 1 reply; 9+ messages in thread
From: Mohammad Abdul Awal @ 2018-05-14 15:42 UTC (permalink / raw)
  To: Iremonger, Bernard, dev, adrien.mazarguil



On 14/05/2018 11:35, Iremonger, Bernard wrote:
> Hi Awal,
>
>> -----Original Message-----
>> From: Awal, Mohammad Abdul
>> Sent: Friday, May 11, 2018 6:14 PM
>> To: dev@dpdk.org; Iremonger, Bernard <bernard.iremonger@intel.com>;
>> adrien.mazarguil@6wind.com
>> Subject: [PATCH v2 2/2] doc/guides: updated testpmd app user guide for
>> vxlan/nvgre encap/decap
>>
>> Updated the testpmd user guide documentation with how to used new action
> Typo, "used" in line above should be "use".
Will fix.
>
>> types RTE_FLOW_ACTION_VXLAN_ENCAP, RTE_FLOW_ACTION_VXLAN_DECAP,
>> RTE_FLOW_ACTION_NVGRE_ENCAP, RTE_FLOW_ACTION_NVGRE_DECAP
>> capabilities.
>>
>> Signed-off-by: Mohammad Abdul Awal <mohammad.abdul.awal@intel.com>
>> ---
>>   doc/guides/testpmd_app_ug/testpmd_funcs.rst | 50
>> +++++++++++++++++++++++++++++
>>   1 file changed, 50 insertions(+)
>>
>> diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
>> b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
>> index 542c217..6ee3ff3 100644
>> --- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
>> +++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
>> @@ -3559,6 +3559,56 @@ This section lists supported actions and their
>> attributes, if any.
>>
>>     - ``ethertype``: Ethertype.
>>
>> +- ``vxlan_encap``: encapsulate the inner flow with pattern of headers
>> +  according to RFC7348.
>> +
>> +  - ``eth_dst {MAC-48}``: outer ether destination.
>> +
>> +  - ``eth_src {MAC-48}``: outer ether source.
>> +
>> +  - ``eth_type {unsigned}``: outer ether type.
>> +
>> +  - ``vlan_tci {unsigned}``: outer vlan tci.
>> +
>> +  - ``ipv4_dst {ipv4 address}``: outer ipv4 destination.
>> +
>> +  - ``ipv4_src {ipv4 address}``: outer ipv4 source.
>> +
>> +  - ``ipv4_proto {unsigned}``: outer ipv4 proto.
>> +
>> +  - ``udp_dst {unsigned}``: outer udp destination.
>> +
>> +  - ``udp_src {unsigned}``: outer udp source.
>> +
>> +  - ``vxlan_vni {unsigned}``: outer vxlan vni.
>> +
>> +  - ``end``: outer vxlan header pattern end.
>> +
>> +- ``vxlan_decap``: decapsulate the vxlan tunnel flow according to RFC7348.
>> +
>> +- ``nvgre_encap``: encapsulate the inner flow with pattern of headers
>> +  according to RFC7637.
>> +
>> +  - ``eth_dst {MAC-48}``: outer ether destination.
>> +
>> +  - ``eth_src {MAC-48}``: outer ether source.
>> +
>> +  - ``eth_type {unsigned}``: outer ether type.
>> +
>> +  - ``vlan_tci {unsigned}``: outer vlan tci.
>> +
>> +  - ``ipv4_dst {ipv4 address}``: outer ipv4 destination.
>> +
>> +  - ``ipv4_src {ipv4 address}``: outer ipv4 source.
>> +
>> +  - ``ipv4_proto {unsigned}``: outer ipv4 proto.
>> +
>> +  - ``nvgre_vsni {unsigned}``: outer nvgre vsni.
>> +
>> +  - ``end``: outer nvgre header pattern end.
>> +
>> +- ``nvgre_decap``: decapsulate the nvgre tunnel flow according to RFC7637.
>> +
>>   Destroying flow rules
>>   ~~~~~~~~~~~~~~~~~~~~~
> I see that section 4.14.1 has been updated to document the syntax of the encap and decap actions, which look fine.
> However my comment on the v1 patch about adding some sample encap and decap rules has not been addressed.
> My understanding is, that it is a two stage process where the tunnel endpoint flow is created first and the encapsulated flow is then created, this is not obvious from the syntax description section.
> I think it would be useful to add some sample flows after section 4.12.8
The two stage process may be a PMD implementation specific. Since we do 
not have any underlying hw yet to exploit the tunnel API, adding a 
specific example will make user more confused. Using the above 
description will enable a user to create a flow to take into account 
nvgre/vxlan encap decap actions.

>> --
>> 2.7.4

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [dpdk-dev] [PATCH v2 2/2] doc/guides: updated testpmd app user guide for vxlan/nvgre encap/decap
  2018-05-14 15:42     ` Mohammad Abdul Awal
@ 2018-06-14 17:14       ` Ferruh Yigit
  2018-06-14 17:19         ` Ferruh Yigit
  0 siblings, 1 reply; 9+ messages in thread
From: Ferruh Yigit @ 2018-06-14 17:14 UTC (permalink / raw)
  To: Mohammad Abdul Awal, Iremonger, Bernard, dev, adrien.mazarguil

On 5/14/2018 4:42 PM, Mohammad Abdul Awal wrote:
> 
> 
> On 14/05/2018 11:35, Iremonger, Bernard wrote:
>> Hi Awal,
>>
>>> -----Original Message-----
>>> From: Awal, Mohammad Abdul
>>> Sent: Friday, May 11, 2018 6:14 PM
>>> To: dev@dpdk.org; Iremonger, Bernard <bernard.iremonger@intel.com>;
>>> adrien.mazarguil@6wind.com
>>> Subject: [PATCH v2 2/2] doc/guides: updated testpmd app user guide for
>>> vxlan/nvgre encap/decap
>>>
>>> Updated the testpmd user guide documentation with how to used new action
>> Typo, "used" in line above should be "use".
> Will fix.

Hi Awal,

If this is the only change I can fix this while merging. Are you planning a new
version of the set?

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [dpdk-dev] [PATCH v2 2/2] doc/guides: updated testpmd app user guide for vxlan/nvgre encap/decap
  2018-06-14 17:14       ` Ferruh Yigit
@ 2018-06-14 17:19         ` Ferruh Yigit
  2018-06-18 11:20           ` Mohammad Abdul Awal
  0 siblings, 1 reply; 9+ messages in thread
From: Ferruh Yigit @ 2018-06-14 17:19 UTC (permalink / raw)
  To: Mohammad Abdul Awal, Iremonger, Bernard, dev, adrien.mazarguil,
	Nelio Laranjeiro

On 6/14/2018 6:14 PM, Ferruh Yigit wrote:
> On 5/14/2018 4:42 PM, Mohammad Abdul Awal wrote:
>>
>>
>> On 14/05/2018 11:35, Iremonger, Bernard wrote:
>>> Hi Awal,
>>>
>>>> -----Original Message-----
>>>> From: Awal, Mohammad Abdul
>>>> Sent: Friday, May 11, 2018 6:14 PM
>>>> To: dev@dpdk.org; Iremonger, Bernard <bernard.iremonger@intel.com>;
>>>> adrien.mazarguil@6wind.com
>>>> Subject: [PATCH v2 2/2] doc/guides: updated testpmd app user guide for
>>>> vxlan/nvgre encap/decap
>>>>
>>>> Updated the testpmd user guide documentation with how to used new action
>>> Typo, "used" in line above should be "use".
>> Will fix.
> 
> Hi Awal,
> 
> If this is the only change I can fix this while merging. Are you planning a new
> version of the set?

I just recognized that Nelio has a set that replaces this one:
https://dpdk.org/dev/patchwork/patch/41144/
https://dpdk.org/dev/patchwork/patch/41145/

Are you OK to continue with above patches and mark this set as superseded?

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [dpdk-dev] [PATCH v2 2/2] doc/guides: updated testpmd app user guide for vxlan/nvgre encap/decap
  2018-06-14 17:19         ` Ferruh Yigit
@ 2018-06-18 11:20           ` Mohammad Abdul Awal
  0 siblings, 0 replies; 9+ messages in thread
From: Mohammad Abdul Awal @ 2018-06-18 11:20 UTC (permalink / raw)
  To: Ferruh Yigit, Iremonger, Bernard, dev, adrien.mazarguil,
	Nelio Laranjeiro

Hi Ferruh,


On 14/06/2018 18:19, Ferruh Yigit wrote:
> On 6/14/2018 6:14 PM, Ferruh Yigit wrote:
>> On 5/14/2018 4:42 PM, Mohammad Abdul Awal wrote:
>>>
>>> On 14/05/2018 11:35, Iremonger, Bernard wrote:
>>>> Hi Awal,
>>>>
>>>>> -----Original Message-----
>>>>> From: Awal, Mohammad Abdul
>>>>> Sent: Friday, May 11, 2018 6:14 PM
>>>>> To: dev@dpdk.org; Iremonger, Bernard <bernard.iremonger@intel.com>;
>>>>> adrien.mazarguil@6wind.com
>>>>> Subject: [PATCH v2 2/2] doc/guides: updated testpmd app user guide for
>>>>> vxlan/nvgre encap/decap
>>>>>
>>>>> Updated the testpmd user guide documentation with how to used new action
>>>> Typo, "used" in line above should be "use".
>>> Will fix.
>> Hi Awal,
>>
>> If this is the only change I can fix this while merging. Are you planning a new
>> version of the set?
> I just recognized that Nelio has a set that replaces this one:
> https://dpdk.org/dev/patchwork/patch/41144/
> https://dpdk.org/dev/patchwork/patch/41145/
>
> Are you OK to continue with above patches and mark this set as superseded?
I am OK marking my patches to be superseded by Neilo's patchset.

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2018-06-18 11:20 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-05-11 17:13 [dpdk-dev] [PATCH v2 0/2] Added vxlan/nvgre encap/decap support to testpmd Mohammad Abdul Awal
2018-05-11 17:14 ` [dpdk-dev] [PATCH v2 1/2] app/testpmd: enabled vxlan and nvgre encap/decap support for rte_flow Mohammad Abdul Awal
2018-05-14 11:14   ` Iremonger, Bernard
2018-05-11 17:14 ` [dpdk-dev] [PATCH v2 2/2] doc/guides: updated testpmd app user guide for vxlan/nvgre encap/decap Mohammad Abdul Awal
2018-05-14 10:35   ` Iremonger, Bernard
2018-05-14 15:42     ` Mohammad Abdul Awal
2018-06-14 17:14       ` Ferruh Yigit
2018-06-14 17:19         ` Ferruh Yigit
2018-06-18 11:20           ` Mohammad Abdul Awal

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).