DPDK patches and discussions
 help / color / mirror / Atom feed
* [dpdk-dev] [PATCH 0/4] support PPPoL2TPv2oUDP RSS Hash
@ 2021-09-24 15:17 Jie Wang
  2021-09-24 15:17 ` [dpdk-dev] [PATCH 1/4] net/iavf: support PPPoL2TPv2oUDP over IPv4 " Jie Wang
                   ` (4 more replies)
  0 siblings, 5 replies; 71+ messages in thread
From: Jie Wang @ 2021-09-24 15:17 UTC (permalink / raw)
  To: dev
  Cc: ferruh.yigit, thomas, andrew.rybchenko, xiaoyun.li, jingjing.wu,
	beilei.xing, wenjun1.wu, stevex.yang, Jie Wang

Support IAVF PPPoL2TPv2oUDP RSS Hash. Required to distribute packets
based on inner IP src+dest address and TCP/UDP src+dest port.

Jie Wang (4):
  net/iavf: support PPPoL2TPv2oUDP over IPv4 RSS Hash
  app/testpmd: support PPPoL2TPv2oUDP RSS Hash
  ethdev: support PPPoL2TPv2oUDP RSS Hash
  net/iavf: support PPPoL2TPv2oUDP over IPv6 RSS Hash

 app/test-pmd/cmdline_flow.c          |  34 +++++++
 drivers/net/iavf/iavf_generic_flow.c | 131 +++++++++++++++++++++++++++
 drivers/net/iavf/iavf_generic_flow.h |  15 +++
 drivers/net/iavf/iavf_hash.c         | 108 +++++++++++++++++++++-
 lib/ethdev/rte_flow.c                |   2 +
 lib/ethdev/rte_flow.h                |  99 ++++++++++++++++++++
 6 files changed, 387 insertions(+), 2 deletions(-)

-- 
2.25.1


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

* [dpdk-dev] [PATCH 1/4] net/iavf: support PPPoL2TPv2oUDP over IPv4 RSS Hash
  2021-09-24 15:17 [dpdk-dev] [PATCH 0/4] support PPPoL2TPv2oUDP RSS Hash Jie Wang
@ 2021-09-24 15:17 ` Jie Wang
  2021-09-24 15:17 ` [dpdk-dev] [PATCH 2/4] app/testpmd: support PPPoL2TPv2oUDP " Jie Wang
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 71+ messages in thread
From: Jie Wang @ 2021-09-24 15:17 UTC (permalink / raw)
  To: dev
  Cc: ferruh.yigit, thomas, andrew.rybchenko, xiaoyun.li, jingjing.wu,
	beilei.xing, wenjun1.wu, stevex.yang, Jie Wang

Add support for PPP over L2TPv2 over UDP over outer IPv4 protocol
RSS Hash based on inner IP src/dst address and TCP/UDP src/dst port.

Signed-off-by: Wenjun Wu <wenjun1.wu@intel.com>
Signed-off-by: Jie Wang <jie1x.wang@intel.com>
---
 drivers/net/iavf/iavf_generic_flow.c |  67 ++++++++++++++++++
 drivers/net/iavf/iavf_generic_flow.h |   9 +++
 drivers/net/iavf/iavf_hash.c         | 102 ++++++++++++++++++++++++++-
 3 files changed, 176 insertions(+), 2 deletions(-)

diff --git a/drivers/net/iavf/iavf_generic_flow.c b/drivers/net/iavf/iavf_generic_flow.c
index 1fe270fb22..ab2f91c57c 100644
--- a/drivers/net/iavf/iavf_generic_flow.c
+++ b/drivers/net/iavf/iavf_generic_flow.c
@@ -1611,6 +1611,73 @@ enum rte_flow_item_type iavf_pattern_eth_ipv6_gre_ipv6_udp[] = {
 	RTE_FLOW_ITEM_TYPE_END,
 };
 
+/* PPPoL2TPv2oUDP */
+enum rte_flow_item_type iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv4[] = {
+	RTE_FLOW_ITEM_TYPE_ETH,
+	RTE_FLOW_ITEM_TYPE_IPV4,
+	RTE_FLOW_ITEM_TYPE_UDP,
+	RTE_FLOW_ITEM_TYPE_L2TPV2,
+	RTE_FLOW_ITEM_TYPE_PPP,
+	RTE_FLOW_ITEM_TYPE_IPV4,
+	RTE_FLOW_ITEM_TYPE_END,
+};
+
+enum rte_flow_item_type iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv6[] = {
+	RTE_FLOW_ITEM_TYPE_ETH,
+	RTE_FLOW_ITEM_TYPE_IPV4,
+	RTE_FLOW_ITEM_TYPE_UDP,
+	RTE_FLOW_ITEM_TYPE_L2TPV2,
+	RTE_FLOW_ITEM_TYPE_PPP,
+	RTE_FLOW_ITEM_TYPE_IPV6,
+	RTE_FLOW_ITEM_TYPE_END,
+};
+
+enum rte_flow_item_type iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv4_udp[] = {
+	RTE_FLOW_ITEM_TYPE_ETH,
+	RTE_FLOW_ITEM_TYPE_IPV4,
+	RTE_FLOW_ITEM_TYPE_UDP,
+	RTE_FLOW_ITEM_TYPE_L2TPV2,
+	RTE_FLOW_ITEM_TYPE_PPP,
+	RTE_FLOW_ITEM_TYPE_IPV4,
+	RTE_FLOW_ITEM_TYPE_UDP,
+	RTE_FLOW_ITEM_TYPE_END,
+};
+
+enum rte_flow_item_type iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv4_tcp[] = {
+	RTE_FLOW_ITEM_TYPE_ETH,
+	RTE_FLOW_ITEM_TYPE_IPV4,
+	RTE_FLOW_ITEM_TYPE_UDP,
+	RTE_FLOW_ITEM_TYPE_L2TPV2,
+	RTE_FLOW_ITEM_TYPE_PPP,
+	RTE_FLOW_ITEM_TYPE_IPV4,
+	RTE_FLOW_ITEM_TYPE_TCP,
+	RTE_FLOW_ITEM_TYPE_END,
+};
+
+enum rte_flow_item_type iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv6_udp[] = {
+	RTE_FLOW_ITEM_TYPE_ETH,
+	RTE_FLOW_ITEM_TYPE_IPV4,
+	RTE_FLOW_ITEM_TYPE_UDP,
+	RTE_FLOW_ITEM_TYPE_L2TPV2,
+	RTE_FLOW_ITEM_TYPE_PPP,
+	RTE_FLOW_ITEM_TYPE_IPV6,
+	RTE_FLOW_ITEM_TYPE_UDP,
+	RTE_FLOW_ITEM_TYPE_END,
+};
+
+enum rte_flow_item_type iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv6_tcp[] = {
+	RTE_FLOW_ITEM_TYPE_ETH,
+	RTE_FLOW_ITEM_TYPE_IPV4,
+	RTE_FLOW_ITEM_TYPE_UDP,
+	RTE_FLOW_ITEM_TYPE_L2TPV2,
+	RTE_FLOW_ITEM_TYPE_PPP,
+	RTE_FLOW_ITEM_TYPE_IPV6,
+	RTE_FLOW_ITEM_TYPE_TCP,
+	RTE_FLOW_ITEM_TYPE_END,
+};
+
+
+
 typedef struct iavf_flow_engine * (*parse_engine_t)(struct iavf_adapter *ad,
 		struct rte_flow *flow,
 		struct iavf_parser_list *parser_list,
diff --git a/drivers/net/iavf/iavf_generic_flow.h b/drivers/net/iavf/iavf_generic_flow.h
index 4794d1fb80..c976b60c79 100644
--- a/drivers/net/iavf/iavf_generic_flow.h
+++ b/drivers/net/iavf/iavf_generic_flow.h
@@ -410,6 +410,15 @@ extern enum rte_flow_item_type iavf_pattern_eth_ipv6_gre_ipv6_tcp[];
 extern enum rte_flow_item_type iavf_pattern_eth_ipv6_gre_ipv4_udp[];
 extern enum rte_flow_item_type iavf_pattern_eth_ipv6_gre_ipv6_udp[];
 
+/* PPPoL2TPv2oUDP */
+extern enum rte_flow_item_type iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv4[];
+extern enum rte_flow_item_type iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv6[];
+extern enum rte_flow_item_type iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv4_udp[];
+extern enum rte_flow_item_type iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv4_tcp[];
+extern enum rte_flow_item_type iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv6_udp[];
+extern enum rte_flow_item_type iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv6_tcp[];
+
+
 extern const struct rte_flow_ops iavf_flow_ops;
 
 /* pattern structure */
diff --git a/drivers/net/iavf/iavf_hash.c b/drivers/net/iavf/iavf_hash.c
index eba55ecea5..e725326d5c 100644
--- a/drivers/net/iavf/iavf_hash.c
+++ b/drivers/net/iavf/iavf_hash.c
@@ -34,6 +34,8 @@
 /* the second IP header of GTPoGRE */
 #define IAVF_PHINT_MID_IPV4			BIT_ULL(7)
 #define IAVF_PHINT_MID_IPV6			BIT_ULL(8)
+/* L2TPV2 */
+#define IAVF_PHINT_L2TPV2			BIT_ULL(9)
 
 #define IAVF_PHINT_GTPU_MSK	(IAVF_PHINT_GTPU	| \
 				 IAVF_PHINT_GTPU_EH	| \
@@ -164,6 +166,12 @@ iavf_hash_parse_pattern_action(struct iavf_adapter *ad,
 	VIRTCHNL_PROTO_HDR_ECPRI, \
 	FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_ECPRI_PC_RTC_ID), {BUFF_NOUSED} }
 
+#define proto_hdr_l2tpv2 { \
+	VIRTCHNL_PROTO_HDR_L2TPV2, 0, {BUFF_NOUSED} }
+
+#define proto_hdr_ppp { \
+	VIRTCHNL_PROTO_HDR_PPP, 0, {BUFF_NOUSED} }
+
 #define TUNNEL_LEVEL_OUTER		0
 #define TUNNEL_LEVEL_INNER		1
 
@@ -338,6 +346,52 @@ struct virtchnl_proto_hdrs ipv4_ecpri_tmplt = {
 	TUNNEL_LEVEL_OUTER, 3, {proto_hdr_ipv4, proto_hdr_udp, proto_hdr_ecpri}
 };
 
+struct virtchnl_proto_hdrs udp_l2tpv2_ppp_ipv4_tmplt = {
+	TUNNEL_LEVEL_INNER, 3,
+	{proto_hdr_l2tpv2,
+	 proto_hdr_ppp,
+	 proto_hdr_ipv4}
+};
+
+struct virtchnl_proto_hdrs udp_l2tpv2_ppp_ipv6_tmplt = {
+	TUNNEL_LEVEL_INNER, 3,
+	{proto_hdr_l2tpv2,
+	 proto_hdr_ppp,
+	 proto_hdr_ipv6}
+};
+
+struct virtchnl_proto_hdrs udp_l2tpv2_ppp_ipv4_udp_tmplt = {
+	TUNNEL_LEVEL_INNER, 4,
+	{proto_hdr_l2tpv2,
+	 proto_hdr_ppp,
+	 proto_hdr_ipv4_with_prot,
+	 proto_hdr_udp}
+};
+
+struct virtchnl_proto_hdrs udp_l2tpv2_ppp_ipv4_tcp_tmplt = {
+	TUNNEL_LEVEL_INNER, 4,
+	{proto_hdr_l2tpv2,
+	 proto_hdr_ppp,
+	 proto_hdr_ipv4_with_prot,
+	 proto_hdr_tcp}
+};
+
+struct virtchnl_proto_hdrs udp_l2tpv2_ppp_ipv6_udp_tmplt = {
+	TUNNEL_LEVEL_INNER, 4,
+	{proto_hdr_l2tpv2,
+	 proto_hdr_ppp,
+	 proto_hdr_ipv6_with_prot,
+	 proto_hdr_udp}
+};
+
+struct virtchnl_proto_hdrs udp_l2tpv2_ppp_ipv6_tcp_tmplt = {
+	TUNNEL_LEVEL_INNER, 4,
+	{proto_hdr_l2tpv2,
+	 proto_hdr_ppp,
+	 proto_hdr_ipv6_with_prot,
+	 proto_hdr_tcp}
+};
+
 /* rss type super set */
 
 /* IPv4 outer */
@@ -486,6 +540,10 @@ static struct iavf_pattern_match_item iavf_hash_pattern_list[] = {
 	{iavf_pattern_eth_ipv6_gre_ipv4_tcp,	IAVF_RSS_TYPE_INNER_IPV4_TCP, &inner_ipv4_tcp_tmplt},
 	{iavf_pattern_eth_ipv4_gre_ipv4_udp,	IAVF_RSS_TYPE_INNER_IPV4_UDP, &inner_ipv4_udp_tmplt},
 	{iavf_pattern_eth_ipv6_gre_ipv4_udp,	IAVF_RSS_TYPE_INNER_IPV4_UDP, &inner_ipv4_udp_tmplt},
+	{iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv4,	IAVF_RSS_TYPE_INNER_IPV4,	&udp_l2tpv2_ppp_ipv4_tmplt},
+	{iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv4_udp,	IAVF_RSS_TYPE_INNER_IPV4_UDP,	&udp_l2tpv2_ppp_ipv4_udp_tmplt},
+	{iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv4_tcp,	IAVF_RSS_TYPE_INNER_IPV4_TCP,	&udp_l2tpv2_ppp_ipv4_tcp_tmplt},
+
 	/* IPv6 */
 	{iavf_pattern_eth_ipv6,				IAVF_RSS_TYPE_OUTER_IPV6,	&outer_ipv6_tmplt},
 	{iavf_pattern_eth_ipv6_frag_ext,		IAVF_RSS_TYPE_OUTER_IPV6_FRAG,	&outer_ipv6_frag_tmplt},
@@ -546,6 +604,10 @@ static struct iavf_pattern_match_item iavf_hash_pattern_list[] = {
 	{iavf_pattern_eth_ipv6_gre_ipv6_tcp,	IAVF_RSS_TYPE_INNER_IPV6_TCP, &inner_ipv6_tcp_tmplt},
 	{iavf_pattern_eth_ipv4_gre_ipv6_udp,	IAVF_RSS_TYPE_INNER_IPV6_UDP, &inner_ipv6_udp_tmplt},
 	{iavf_pattern_eth_ipv6_gre_ipv6_udp,	IAVF_RSS_TYPE_INNER_IPV6_UDP, &inner_ipv6_udp_tmplt},
+	{iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv6,	IAVF_RSS_TYPE_INNER_IPV6,	&udp_l2tpv2_ppp_ipv6_tmplt},
+	{iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv6_udp,	IAVF_RSS_TYPE_INNER_IPV6_UDP,	&udp_l2tpv2_ppp_ipv6_udp_tmplt},
+	{iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv6_tcp,	IAVF_RSS_TYPE_INNER_IPV6_TCP,	&udp_l2tpv2_ppp_ipv6_tcp_tmplt},
+
 };
 
 static struct iavf_flow_engine iavf_hash_engine = {
@@ -690,13 +752,17 @@ iavf_hash_parse_pattern(const struct rte_flow_item pattern[], uint64_t *phint,
 
 		switch (item->type) {
 		case RTE_FLOW_ITEM_TYPE_IPV4:
-			if (!(*phint & IAVF_PHINT_GTPU_MSK) && !(*phint & IAVF_PHINT_GRE))
+			if (!(*phint & IAVF_PHINT_GTPU_MSK) &&
+			    !(*phint & IAVF_PHINT_GRE) &&
+			    !(*phint & IAVF_PHINT_L2TPV2))
 				*phint |= IAVF_PHINT_OUTER_IPV4;
 			if ((*phint & IAVF_PHINT_GRE) && !(*phint & IAVF_PHINT_GTPU_MSK))
 				*phint |= IAVF_PHINT_MID_IPV4;
 			break;
 		case RTE_FLOW_ITEM_TYPE_IPV6:
-			if (!(*phint & IAVF_PHINT_GTPU_MSK) && !(*phint & IAVF_PHINT_GRE))
+			if (!(*phint & IAVF_PHINT_GTPU_MSK) &&
+			    !(*phint & IAVF_PHINT_GRE) &&
+			    !(*phint & IAVF_PHINT_L2TPV2))
 				*phint |= IAVF_PHINT_OUTER_IPV6;
 			if ((*phint & IAVF_PHINT_GRE) && !(*phint & IAVF_PHINT_GTPU_MSK))
 				*phint |= IAVF_PHINT_MID_IPV6;
@@ -731,6 +797,10 @@ iavf_hash_parse_pattern(const struct rte_flow_item pattern[], uint64_t *phint,
 			break;
 		case RTE_FLOW_ITEM_TYPE_GRE:
 			*phint |= IAVF_PHINT_GRE;
+			break;
+		case RTE_FLOW_ITEM_TYPE_L2TPV2:
+			*phint |= IAVF_PHINT_L2TPV2;
+			break;
 		default:
 			break;
 		}
@@ -1036,12 +1106,40 @@ iavf_refine_proto_hdrs_by_pattern(struct virtchnl_proto_hdrs *proto_hdrs,
 	proto_hdrs->tunnel_level = tun_lvl;
 }
 
+static void
+iavf_refine_proto_hdrs_l2tpv2(struct virtchnl_proto_hdrs *proto_hdrs,
+			      uint64_t phint)
+{
+	struct virtchnl_proto_hdr *hdr1;
+	int i;
+
+	if (!(phint & IAVF_PHINT_L2TPV2))
+		return;
+
+	if (proto_hdrs->tunnel_level == TUNNEL_LEVEL_INNER) {
+		/* shift headers layer */
+		for (i = proto_hdrs->count - 1 + 1; i > 0; i--)
+			proto_hdrs->proto_hdr[i] = proto_hdrs->proto_hdr[i - 1];
+
+		/* adding outer ip header at layer 0 */
+		hdr1 = &proto_hdrs->proto_hdr[0];
+		hdr1->field_selector = 0;
+		proto_hdrs->count++;
+		proto_hdrs->tunnel_level = TUNNEL_LEVEL_OUTER;
+		if (phint & IAVF_PHINT_OUTER_IPV4)
+			VIRTCHNL_SET_PROTO_HDR_TYPE(hdr1, IPV4);
+		else if (phint & IAVF_PHINT_OUTER_IPV6)
+			VIRTCHNL_SET_PROTO_HDR_TYPE(hdr1, IPV6);
+	}
+}
+
 static void iavf_refine_proto_hdrs(struct virtchnl_proto_hdrs *proto_hdrs,
 				   uint64_t rss_type, uint64_t phint)
 {
 	iavf_refine_proto_hdrs_l234(proto_hdrs, rss_type);
 	iavf_refine_proto_hdrs_by_pattern(proto_hdrs, phint);
 	iavf_refine_proto_hdrs_gtpu(proto_hdrs, rss_type);
+	iavf_refine_proto_hdrs_l2tpv2(proto_hdrs, phint);
 }
 
 static uint64_t invalid_rss_comb[] = {
-- 
2.25.1


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

* [dpdk-dev] [PATCH 2/4] app/testpmd: support PPPoL2TPv2oUDP RSS Hash
  2021-09-24 15:17 [dpdk-dev] [PATCH 0/4] support PPPoL2TPv2oUDP RSS Hash Jie Wang
  2021-09-24 15:17 ` [dpdk-dev] [PATCH 1/4] net/iavf: support PPPoL2TPv2oUDP over IPv4 " Jie Wang
@ 2021-09-24 15:17 ` Jie Wang
  2021-09-24 15:17 ` [dpdk-dev] [PATCH 3/4] ethdev: " Jie Wang
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 71+ messages in thread
From: Jie Wang @ 2021-09-24 15:17 UTC (permalink / raw)
  To: dev
  Cc: ferruh.yigit, thomas, andrew.rybchenko, xiaoyun.li, jingjing.wu,
	beilei.xing, wenjun1.wu, stevex.yang, Jie Wang

Add support for test-pmd to parse protocol pattern L2TPv2 and PPP.

Signed-off-by: Wenjun Wu <wenjun1.wu@intel.com>
Signed-off-by: Jie Wang <jie1x.wang@intel.com>
---
 app/test-pmd/cmdline_flow.c | 34 ++++++++++++++++++++++++++++++++++
 1 file changed, 34 insertions(+)

diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
index 6cd99bf37f..31016455f2 100644
--- a/app/test-pmd/cmdline_flow.c
+++ b/app/test-pmd/cmdline_flow.c
@@ -299,6 +299,8 @@ enum index {
 	ITEM_GENEVE_OPT_TYPE,
 	ITEM_GENEVE_OPT_LENGTH,
 	ITEM_GENEVE_OPT_DATA,
+	ITEM_PPP,
+	ITEM_L2TPV2,
 	ITEM_INTEGRITY,
 	ITEM_INTEGRITY_LEVEL,
 	ITEM_INTEGRITY_VALUE,
@@ -997,6 +999,8 @@ static const enum index next_item[] = {
 	ITEM_AH,
 	ITEM_PFCP,
 	ITEM_ECPRI,
+	ITEM_PPP,
+	ITEM_L2TPV2,
 	ITEM_GENEVE_OPT,
 	ITEM_INTEGRITY,
 	ITEM_CONNTRACK,
@@ -1368,6 +1372,16 @@ static const enum index item_integrity_lv[] = {
 	ZERO,
 };
 
+static const enum index item_ppp[] = {
+	ITEM_NEXT,
+	ZERO,
+};
+
+static const enum index item_l2tpv2[] = {
+	ITEM_NEXT,
+	ZERO,
+};
+
 static const enum index next_action[] = {
 	ACTION_END,
 	ACTION_VOID,
@@ -3579,6 +3593,20 @@ static const struct token token_list[] = {
 				(sizeof(struct rte_flow_item_geneve_opt),
 				ITEM_GENEVE_OPT_DATA_SIZE)),
 	},
+	[ITEM_PPP] = {
+		.name = "ppp",
+		.help = "match ppp header",
+		.priv = PRIV_ITEM(PPP, sizeof(struct rte_flow_item_ppp)),
+		.next = NEXT(item_ppp),
+		.call = parse_vc,
+	},
+	[ITEM_L2TPV2] = {
+		.name = "l2tpv2",
+		.help = "match l2tpv2 header",
+		.priv = PRIV_ITEM(L2TPV2, sizeof(struct rte_flow_item_l2tpv2)),
+		.next = NEXT(item_l2tpv2),
+		.call = parse_vc,
+	},
 	[ITEM_INTEGRITY] = {
 		.name = "integrity",
 		.help = "match packet integrity",
@@ -8343,6 +8371,12 @@ flow_item_default_mask(const struct rte_flow_item *item)
 	case RTE_FLOW_ITEM_TYPE_PFCP:
 		mask = &rte_flow_item_pfcp_mask;
 		break;
+	case RTE_FLOW_ITEM_TYPE_L2TPV2:
+		mask = &rte_flow_item_l2tpv2_mask;
+		break;
+	case RTE_FLOW_ITEM_TYPE_PPP:
+		mask = &rte_flow_item_ppp_mask;
+		break;
 	default:
 		break;
 	}
-- 
2.25.1


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

* [dpdk-dev] [PATCH 3/4] ethdev: support PPPoL2TPv2oUDP RSS Hash
  2021-09-24 15:17 [dpdk-dev] [PATCH 0/4] support PPPoL2TPv2oUDP RSS Hash Jie Wang
  2021-09-24 15:17 ` [dpdk-dev] [PATCH 1/4] net/iavf: support PPPoL2TPv2oUDP over IPv4 " Jie Wang
  2021-09-24 15:17 ` [dpdk-dev] [PATCH 2/4] app/testpmd: support PPPoL2TPv2oUDP " Jie Wang
@ 2021-09-24 15:17 ` Jie Wang
  2021-09-30 14:38   ` Ori Kam
  2021-09-24 15:17 ` [dpdk-dev] [PATCH 4/4] net/iavf: support PPPoL2TPv2oUDP over IPv6 " Jie Wang
  2021-10-12 10:25 ` [dpdk-dev] [PATCH v2 0/3] support PPPoL2TPv2oUDP " Jie Wang
  4 siblings, 1 reply; 71+ messages in thread
From: Jie Wang @ 2021-09-24 15:17 UTC (permalink / raw)
  To: dev
  Cc: ferruh.yigit, thomas, andrew.rybchenko, xiaoyun.li, jingjing.wu,
	beilei.xing, wenjun1.wu, stevex.yang, Jie Wang

Add flow pattern items, RSS offload types and header formats
of L2TPv2 and PPP.

Signed-off-by: Wenjun Wu <wenjun1.wu@intel.com>
Signed-off-by: Jie Wang <jie1x.wang@intel.com>
---
 lib/ethdev/rte_flow.c |  2 +
 lib/ethdev/rte_flow.h | 99 +++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 101 insertions(+)

diff --git a/lib/ethdev/rte_flow.c b/lib/ethdev/rte_flow.c
index 8cb7a069c8..307fbc3abe 100644
--- a/lib/ethdev/rte_flow.c
+++ b/lib/ethdev/rte_flow.c
@@ -98,6 +98,8 @@ static const struct rte_flow_desc_data rte_flow_desc_item[] = {
 	MK_FLOW_ITEM(PFCP, sizeof(struct rte_flow_item_pfcp)),
 	MK_FLOW_ITEM(ECPRI, sizeof(struct rte_flow_item_ecpri)),
 	MK_FLOW_ITEM(GENEVE_OPT, sizeof(struct rte_flow_item_geneve_opt)),
+	MK_FLOW_ITEM(L2TPV2, sizeof(struct rte_flow_item_l2tpv2)),
+	MK_FLOW_ITEM(PPP, sizeof(struct rte_flow_item_ppp)),
 	MK_FLOW_ITEM(INTEGRITY, sizeof(struct rte_flow_item_integrity)),
 	MK_FLOW_ITEM(CONNTRACK, sizeof(uint32_t)),
 };
diff --git a/lib/ethdev/rte_flow.h b/lib/ethdev/rte_flow.h
index 70f455d47d..93205b7d1e 100644
--- a/lib/ethdev/rte_flow.h
+++ b/lib/ethdev/rte_flow.h
@@ -554,6 +554,20 @@ enum rte_flow_item_type {
 	 */
 	RTE_FLOW_ITEM_TYPE_GENEVE_OPT,
 
+	/**
+	 * Matches L2TPV2 Header.
+	 *
+	 * See struct rte_flow_item_l2tpv2.
+	 */
+	RTE_FLOW_ITEM_TYPE_L2TPV2,
+
+	/**
+	 * Matches PPP Header.
+	 *
+	 * See struct rte_flow_item_ppp.
+	 */
+	RTE_FLOW_ITEM_TYPE_PPP,
+
 	/**
 	 * [META]
 	 *
@@ -1799,6 +1813,91 @@ static const struct rte_flow_item_conntrack rte_flow_item_conntrack_mask = {
 };
 #endif
 
+/**
+ * @warning
+ * @b EXPERIMENTAL: this structure may change without prior notice
+ * RTE_FLOW_ITEM_TYPE_L2TPV2
+ *
+ * Matches L2TPv2 Header
+ */
+RTE_STD_C11
+struct rte_flow_item_l2tpv2 {
+	rte_be16_t flags_version;   /**< flag(12)  version(2). version must be 2 */
+	union{
+		struct{
+			rte_be16_t length;  /**< length(16) */
+			rte_be16_t tunnel_id;   /**< tunnel id(16) */
+			rte_be16_t session_id;  /**< session id(16) */
+			rte_be32_t ns_nr;   /**< Ns(16) + Nr(16) */
+			rte_be32_t offset;  /**< offset size(16) + offset padding(16) */
+		} type1;
+		struct{
+			rte_be16_t tunnel_id;   /**< tunnel id(16) */
+			rte_be16_t session_id;  /**< session id(16) */
+			rte_be32_t ns_nr;   /**< Ns(16) + Nr(16) */
+			rte_be32_t offset;  /**< offset size(16) + offset padding(16) */
+		} type2;
+		struct{
+			rte_be16_t length;  /**< length(16) */
+			rte_be16_t tunnel_id;   /**< tunnel id(16) */
+			rte_be16_t session_id;  /**< session id(16) */
+			rte_be32_t offset;  /**< offset size(16) + offset padding(16) */
+		} type3;
+		struct{
+			rte_be16_t length;  /**< length(16) */
+			rte_be16_t tunnel_id;   /**< tunnel id(16) */
+			rte_be16_t session_id;  /**< session id(16) */
+			rte_be32_t ns_nr;   /**< Ns(16) + Nr(16) */
+		} type4;
+		struct{
+			rte_be16_t tunnel_id;   /**< tunnel id(16) */
+			rte_be16_t session_id;  /**< session id(16) */
+			rte_be32_t offset;  /**< offset size(16) + offset padding(16) */
+		} type5;
+		struct{
+			rte_be16_t tunnel_id;   /**< tunnel id(16) */
+			rte_be16_t session_id;  /**< session id(16) */
+			rte_be32_t ns_nr;   /**< Ns(16) + Nr(16) */
+		} type6;
+		struct{
+			rte_be16_t length;  /**< length(16) */
+			rte_be16_t tunnel_id;   /**< tunnel id(16) */
+			rte_be16_t session_id;  /**< session id(16) */
+		} type7;
+		struct{
+			rte_be16_t tunnel_id;   /**< tunnel id(16) */
+			rte_be16_t session_id;  /**< session id(16) */
+		} type8;
+	};
+};
+
+/** Default mask for RTE_FLOW_ITEM_TYPE_L2TPV2. */
+#ifndef __cplusplus
+static const struct rte_flow_item_l2tpv2 rte_flow_item_l2tpv2_mask = {
+	.flags_version = 0xffff,
+};
+#endif
+
+/**
+ * @warning
+ * @b EXPERIMENTAL: this structure may change without prior notice
+ * RTE_FLOW_ITEM_TYPE_PPP
+ *
+ * Matches PPP Header
+ */
+struct rte_flow_item_ppp {
+	rte_be16_t pppaddr_ctrl; /**< ppp address(8) + control(8) */
+	rte_be16_t pppproto_id; /**< ppp protocol id(16) */
+};
+
+/** Default mask for RTE_FLOW_ITEM_TYPE_PPP. */
+#ifndef __cplusplus
+static const struct rte_flow_item_ppp rte_flow_item_ppp_mask = {
+	.pppaddr_ctrl = 0xffff,
+	.pppproto_id = 0xffff,
+};
+#endif
+
 /**
  * Matching pattern item definition.
  *
-- 
2.25.1


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

* [dpdk-dev] [PATCH 4/4] net/iavf: support PPPoL2TPv2oUDP over IPv6 RSS Hash
  2021-09-24 15:17 [dpdk-dev] [PATCH 0/4] support PPPoL2TPv2oUDP RSS Hash Jie Wang
                   ` (2 preceding siblings ...)
  2021-09-24 15:17 ` [dpdk-dev] [PATCH 3/4] ethdev: " Jie Wang
@ 2021-09-24 15:17 ` Jie Wang
  2021-10-12 10:25 ` [dpdk-dev] [PATCH v2 0/3] support PPPoL2TPv2oUDP " Jie Wang
  4 siblings, 0 replies; 71+ messages in thread
From: Jie Wang @ 2021-09-24 15:17 UTC (permalink / raw)
  To: dev
  Cc: ferruh.yigit, thomas, andrew.rybchenko, xiaoyun.li, jingjing.wu,
	beilei.xing, wenjun1.wu, stevex.yang, Jie Wang

Add support for PPP over L2TPv2 over UDP over outer ipv6 protocol
RSS Hash based on inner IP src/dst address and TCP/UDP src/dst port.

Signed-off-by: Jie Wang <jie1x.wang@intel.com>
---
 drivers/net/iavf/iavf_generic_flow.c | 64 ++++++++++++++++++++++++++++
 drivers/net/iavf/iavf_generic_flow.h |  6 +++
 drivers/net/iavf/iavf_hash.c         |  6 +++
 3 files changed, 76 insertions(+)

diff --git a/drivers/net/iavf/iavf_generic_flow.c b/drivers/net/iavf/iavf_generic_flow.c
index ab2f91c57c..33ec57f8bc 100644
--- a/drivers/net/iavf/iavf_generic_flow.c
+++ b/drivers/net/iavf/iavf_generic_flow.c
@@ -1676,6 +1676,70 @@ enum rte_flow_item_type iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv6_tcp[] = {
 	RTE_FLOW_ITEM_TYPE_END,
 };
 
+enum rte_flow_item_type iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv4[] = {
+	RTE_FLOW_ITEM_TYPE_ETH,
+	RTE_FLOW_ITEM_TYPE_IPV6,
+	RTE_FLOW_ITEM_TYPE_UDP,
+	RTE_FLOW_ITEM_TYPE_L2TPV2,
+	RTE_FLOW_ITEM_TYPE_PPP,
+	RTE_FLOW_ITEM_TYPE_IPV4,
+	RTE_FLOW_ITEM_TYPE_END,
+};
+
+enum rte_flow_item_type iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv6[] = {
+	RTE_FLOW_ITEM_TYPE_ETH,
+	RTE_FLOW_ITEM_TYPE_IPV6,
+	RTE_FLOW_ITEM_TYPE_UDP,
+	RTE_FLOW_ITEM_TYPE_L2TPV2,
+	RTE_FLOW_ITEM_TYPE_PPP,
+	RTE_FLOW_ITEM_TYPE_IPV6,
+	RTE_FLOW_ITEM_TYPE_END,
+};
+
+enum rte_flow_item_type iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv4_udp[] = {
+	RTE_FLOW_ITEM_TYPE_ETH,
+	RTE_FLOW_ITEM_TYPE_IPV6,
+	RTE_FLOW_ITEM_TYPE_UDP,
+	RTE_FLOW_ITEM_TYPE_L2TPV2,
+	RTE_FLOW_ITEM_TYPE_PPP,
+	RTE_FLOW_ITEM_TYPE_IPV4,
+	RTE_FLOW_ITEM_TYPE_UDP,
+	RTE_FLOW_ITEM_TYPE_END,
+};
+
+enum rte_flow_item_type iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv4_tcp[] = {
+	RTE_FLOW_ITEM_TYPE_ETH,
+	RTE_FLOW_ITEM_TYPE_IPV6,
+	RTE_FLOW_ITEM_TYPE_UDP,
+	RTE_FLOW_ITEM_TYPE_L2TPV2,
+	RTE_FLOW_ITEM_TYPE_PPP,
+	RTE_FLOW_ITEM_TYPE_IPV4,
+	RTE_FLOW_ITEM_TYPE_TCP,
+	RTE_FLOW_ITEM_TYPE_END,
+};
+
+enum rte_flow_item_type iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv6_udp[] = {
+	RTE_FLOW_ITEM_TYPE_ETH,
+	RTE_FLOW_ITEM_TYPE_IPV6,
+	RTE_FLOW_ITEM_TYPE_UDP,
+	RTE_FLOW_ITEM_TYPE_L2TPV2,
+	RTE_FLOW_ITEM_TYPE_PPP,
+	RTE_FLOW_ITEM_TYPE_IPV6,
+	RTE_FLOW_ITEM_TYPE_UDP,
+	RTE_FLOW_ITEM_TYPE_END,
+};
+
+enum rte_flow_item_type iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv6_tcp[] = {
+	RTE_FLOW_ITEM_TYPE_ETH,
+	RTE_FLOW_ITEM_TYPE_IPV6,
+	RTE_FLOW_ITEM_TYPE_UDP,
+	RTE_FLOW_ITEM_TYPE_L2TPV2,
+	RTE_FLOW_ITEM_TYPE_PPP,
+	RTE_FLOW_ITEM_TYPE_IPV6,
+	RTE_FLOW_ITEM_TYPE_TCP,
+	RTE_FLOW_ITEM_TYPE_END,
+};
+
 
 
 typedef struct iavf_flow_engine * (*parse_engine_t)(struct iavf_adapter *ad,
diff --git a/drivers/net/iavf/iavf_generic_flow.h b/drivers/net/iavf/iavf_generic_flow.h
index c976b60c79..f2b54e1944 100644
--- a/drivers/net/iavf/iavf_generic_flow.h
+++ b/drivers/net/iavf/iavf_generic_flow.h
@@ -417,6 +417,12 @@ extern enum rte_flow_item_type iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv4_udp[];
 extern enum rte_flow_item_type iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv4_tcp[];
 extern enum rte_flow_item_type iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv6_udp[];
 extern enum rte_flow_item_type iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv6_tcp[];
+extern enum rte_flow_item_type iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv4[];
+extern enum rte_flow_item_type iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv6[];
+extern enum rte_flow_item_type iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv4_udp[];
+extern enum rte_flow_item_type iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv4_tcp[];
+extern enum rte_flow_item_type iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv6_udp[];
+extern enum rte_flow_item_type iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv6_tcp[];
 
 
 extern const struct rte_flow_ops iavf_flow_ops;
diff --git a/drivers/net/iavf/iavf_hash.c b/drivers/net/iavf/iavf_hash.c
index e725326d5c..b240c22b5a 100644
--- a/drivers/net/iavf/iavf_hash.c
+++ b/drivers/net/iavf/iavf_hash.c
@@ -543,6 +543,9 @@ static struct iavf_pattern_match_item iavf_hash_pattern_list[] = {
 	{iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv4,	IAVF_RSS_TYPE_INNER_IPV4,	&udp_l2tpv2_ppp_ipv4_tmplt},
 	{iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv4_udp,	IAVF_RSS_TYPE_INNER_IPV4_UDP,	&udp_l2tpv2_ppp_ipv4_udp_tmplt},
 	{iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv4_tcp,	IAVF_RSS_TYPE_INNER_IPV4_TCP,	&udp_l2tpv2_ppp_ipv4_tcp_tmplt},
+	{iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv4,	IAVF_RSS_TYPE_INNER_IPV4,	&udp_l2tpv2_ppp_ipv4_tmplt},
+	{iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv4_udp,	IAVF_RSS_TYPE_INNER_IPV4_UDP,	&udp_l2tpv2_ppp_ipv4_udp_tmplt},
+	{iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv4_tcp,	IAVF_RSS_TYPE_INNER_IPV4_TCP,	&udp_l2tpv2_ppp_ipv4_tcp_tmplt},
 
 	/* IPv6 */
 	{iavf_pattern_eth_ipv6,				IAVF_RSS_TYPE_OUTER_IPV6,	&outer_ipv6_tmplt},
@@ -607,6 +610,9 @@ static struct iavf_pattern_match_item iavf_hash_pattern_list[] = {
 	{iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv6,	IAVF_RSS_TYPE_INNER_IPV6,	&udp_l2tpv2_ppp_ipv6_tmplt},
 	{iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv6_udp,	IAVF_RSS_TYPE_INNER_IPV6_UDP,	&udp_l2tpv2_ppp_ipv6_udp_tmplt},
 	{iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv6_tcp,	IAVF_RSS_TYPE_INNER_IPV6_TCP,	&udp_l2tpv2_ppp_ipv6_tcp_tmplt},
+	{iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv6,	IAVF_RSS_TYPE_INNER_IPV6,	&udp_l2tpv2_ppp_ipv6_tmplt},
+	{iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv6_udp,	IAVF_RSS_TYPE_INNER_IPV6_UDP,	&udp_l2tpv2_ppp_ipv6_udp_tmplt},
+	{iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv6_tcp,	IAVF_RSS_TYPE_INNER_IPV6_TCP,	&udp_l2tpv2_ppp_ipv6_tcp_tmplt},
 
 };
 
-- 
2.25.1


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

* Re: [dpdk-dev] [PATCH 3/4] ethdev: support PPPoL2TPv2oUDP RSS Hash
  2021-09-24 15:17 ` [dpdk-dev] [PATCH 3/4] ethdev: " Jie Wang
@ 2021-09-30 14:38   ` Ori Kam
  2021-10-05 14:42     ` Ferruh Yigit
  0 siblings, 1 reply; 71+ messages in thread
From: Ori Kam @ 2021-09-30 14:38 UTC (permalink / raw)
  To: Jie Wang, dev
  Cc: ferruh.yigit, NBU-Contact-Thomas Monjalon, andrew.rybchenko,
	xiaoyun.li, jingjing.wu, beilei.xing, wenjun1.wu, stevex.yang

Hi Jie,

You are missing updating the rte_flow.rst and release notes:

Please see more comments below.

Thanks,
Ori

> -----Original Message-----
> From: dev <dev-bounces@dpdk.org> On Behalf Of Jie Wang
> Sent: Friday, September 24, 2021 6:17 PM
> Subject: [dpdk-dev] [PATCH 3/4] ethdev: support PPPoL2TPv2oUDP RSS
> Hash
> 
> Add flow pattern items, RSS offload types and header formats of L2TPv2 and
> PPP.
> 
> Signed-off-by: Wenjun Wu <wenjun1.wu@intel.com>
> Signed-off-by: Jie Wang <jie1x.wang@intel.com>
> ---
>  lib/ethdev/rte_flow.c |  2 +
>  lib/ethdev/rte_flow.h | 99
> +++++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 101 insertions(+)
> 
> diff --git a/lib/ethdev/rte_flow.c b/lib/ethdev/rte_flow.c index
> 8cb7a069c8..307fbc3abe 100644
> --- a/lib/ethdev/rte_flow.c
> +++ b/lib/ethdev/rte_flow.c
> @@ -98,6 +98,8 @@ static const struct rte_flow_desc_data
> rte_flow_desc_item[] = {
>  	MK_FLOW_ITEM(PFCP, sizeof(struct rte_flow_item_pfcp)),
>  	MK_FLOW_ITEM(ECPRI, sizeof(struct rte_flow_item_ecpri)),
>  	MK_FLOW_ITEM(GENEVE_OPT, sizeof(struct
> rte_flow_item_geneve_opt)),
> +	MK_FLOW_ITEM(L2TPV2, sizeof(struct rte_flow_item_l2tpv2)),
> +	MK_FLOW_ITEM(PPP, sizeof(struct rte_flow_item_ppp)),
>  	MK_FLOW_ITEM(INTEGRITY, sizeof(struct rte_flow_item_integrity)),
>  	MK_FLOW_ITEM(CONNTRACK, sizeof(uint32_t)),  }; diff --git
> a/lib/ethdev/rte_flow.h b/lib/ethdev/rte_flow.h index
> 70f455d47d..93205b7d1e 100644
> --- a/lib/ethdev/rte_flow.h
> +++ b/lib/ethdev/rte_flow.h
> @@ -554,6 +554,20 @@ enum rte_flow_item_type {
>  	 */
>  	RTE_FLOW_ITEM_TYPE_GENEVE_OPT,
> 
> +	/**
> +	 * Matches L2TPV2 Header.
> +	 *
> +	 * See struct rte_flow_item_l2tpv2.
> +	 */
> +	RTE_FLOW_ITEM_TYPE_L2TPV2,
> +
> +	/**
> +	 * Matches PPP Header.
> +	 *
> +	 * See struct rte_flow_item_ppp.
> +	 */
> +	RTE_FLOW_ITEM_TYPE_PPP,
> +

Why did you push the new items here and not in the end?

>  	/**
>  	 * [META]
>  	 *
> @@ -1799,6 +1813,91 @@ static const struct rte_flow_item_conntrack
> rte_flow_item_conntrack_mask = {  };  #endif
> 
> +/**
> + * @warning
> + * @b EXPERIMENTAL: this structure may change without prior notice
> + * RTE_FLOW_ITEM_TYPE_L2TPV2
> + *
> + * Matches L2TPv2 Header
> + */
> +RTE_STD_C11
> +struct rte_flow_item_l2tpv2 {
> +	rte_be16_t flags_version;   /**< flag(12)  version(2). version must be
> 2 */
> +	union{
> +		struct{
> +			rte_be16_t length;  /**< length(16) */
> +			rte_be16_t tunnel_id;   /**< tunnel id(16) */
> +			rte_be16_t session_id;  /**< session id(16) */
> +			rte_be32_t ns_nr;   /**< Ns(16) + Nr(16) */

Why not split those fields? 

> +			rte_be32_t offset;  /**< offset size(16) + offset
> padding(16) */

Why not split those fields?

> +		} type1;
> +		struct{
> +			rte_be16_t tunnel_id;   /**< tunnel id(16) */
> +			rte_be16_t session_id;  /**< session id(16) */
> +			rte_be32_t ns_nr;   /**< Ns(16) + Nr(16) */
> +			rte_be32_t offset;  /**< offset size(16) + offset
> padding(16) */
> +		} type2;
> +		struct{
> +			rte_be16_t length;  /**< length(16) */
> +			rte_be16_t tunnel_id;   /**< tunnel id(16) */
> +			rte_be16_t session_id;  /**< session id(16) */
> +			rte_be32_t offset;  /**< offset size(16) + offset
> padding(16) */
> +		} type3;
> +		struct{
> +			rte_be16_t length;  /**< length(16) */
> +			rte_be16_t tunnel_id;   /**< tunnel id(16) */
> +			rte_be16_t session_id;  /**< session id(16) */
> +			rte_be32_t ns_nr;   /**< Ns(16) + Nr(16) */
> +		} type4;
> +		struct{
> +			rte_be16_t tunnel_id;   /**< tunnel id(16) */
> +			rte_be16_t session_id;  /**< session id(16) */
> +			rte_be32_t offset;  /**< offset size(16) + offset
> padding(16) */
> +		} type5;
> +		struct{
> +			rte_be16_t tunnel_id;   /**< tunnel id(16) */
> +			rte_be16_t session_id;  /**< session id(16) */
> +			rte_be32_t ns_nr;   /**< Ns(16) + Nr(16) */
> +		} type6;
> +		struct{
> +			rte_be16_t length;  /**< length(16) */
> +			rte_be16_t tunnel_id;   /**< tunnel id(16) */
> +			rte_be16_t session_id;  /**< session id(16) */
> +		} type7;
> +		struct{
> +			rte_be16_t tunnel_id;   /**< tunnel id(16) */
> +			rte_be16_t session_id;  /**< session id(16) */
> +		} type8;
> +	};
> +};
> +

The size of each of the types is different so using this struct as is will be hard
if someone wish to use it for encap or just as header.
Why not creating different structs for each type?

> +/** Default mask for RTE_FLOW_ITEM_TYPE_L2TPV2. */ #ifndef
> __cplusplus
> +static const struct rte_flow_item_l2tpv2 rte_flow_item_l2tpv2_mask = {
> +	.flags_version = 0xffff,

Should the default be match on all the flags? And the version?

> +};
> +#endif
> +
> +/**
> + * @warning
> + * @b EXPERIMENTAL: this structure may change without prior notice
> + * RTE_FLOW_ITEM_TYPE_PPP
> + *
> + * Matches PPP Header
> + */
> +struct rte_flow_item_ppp {
> +	rte_be16_t pppaddr_ctrl; /**< ppp address(8) + control(8) */

Why not split?

> +	rte_be16_t pppproto_id; /**< ppp protocol id(16) */ };
> +
> +/** Default mask for RTE_FLOW_ITEM_TYPE_PPP. */ #ifndef __cplusplus
> +static const struct rte_flow_item_ppp rte_flow_item_ppp_mask = {
> +	.pppaddr_ctrl = 0xffff,
> +	.pppproto_id = 0xffff,
> +};
> +#endif
> +
>  /**
>   * Matching pattern item definition.
>   *
> --
> 2.25.1


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

* Re: [dpdk-dev] [PATCH 3/4] ethdev: support PPPoL2TPv2oUDP RSS Hash
  2021-09-30 14:38   ` Ori Kam
@ 2021-10-05 14:42     ` Ferruh Yigit
  2021-10-05 15:06       ` Ori Kam
  0 siblings, 1 reply; 71+ messages in thread
From: Ferruh Yigit @ 2021-10-05 14:42 UTC (permalink / raw)
  To: Ori Kam, Jie Wang, dev, andrew.rybchenko
  Cc: NBU-Contact-Thomas Monjalon, xiaoyun.li, jingjing.wu,
	beilei.xing, wenjun1.wu, stevex.yang

On 9/30/2021 3:38 PM, Ori Kam wrote:
> Hi Jie,
> 
> You are missing updating the rte_flow.rst and release notes:
> 
> Please see more comments below.
> 
> Thanks,
> Ori
> 
>> -----Original Message-----
>> From: dev <dev-bounces@dpdk.org> On Behalf Of Jie Wang
>> Sent: Friday, September 24, 2021 6:17 PM
>> Subject: [dpdk-dev] [PATCH 3/4] ethdev: support PPPoL2TPv2oUDP RSS
>> Hash
>>
>> Add flow pattern items, RSS offload types and header formats of L2TPv2 and
>> PPP.
>>
>> Signed-off-by: Wenjun Wu <wenjun1.wu@intel.com>
>> Signed-off-by: Jie Wang <jie1x.wang@intel.com>
>> ---
>>   lib/ethdev/rte_flow.c |  2 +
>>   lib/ethdev/rte_flow.h | 99
>> +++++++++++++++++++++++++++++++++++++++++++
>>   2 files changed, 101 insertions(+)
>>
>> diff --git a/lib/ethdev/rte_flow.c b/lib/ethdev/rte_flow.c index
>> 8cb7a069c8..307fbc3abe 100644
>> --- a/lib/ethdev/rte_flow.c
>> +++ b/lib/ethdev/rte_flow.c
>> @@ -98,6 +98,8 @@ static const struct rte_flow_desc_data
>> rte_flow_desc_item[] = {
>>   	MK_FLOW_ITEM(PFCP, sizeof(struct rte_flow_item_pfcp)),
>>   	MK_FLOW_ITEM(ECPRI, sizeof(struct rte_flow_item_ecpri)),
>>   	MK_FLOW_ITEM(GENEVE_OPT, sizeof(struct
>> rte_flow_item_geneve_opt)),
>> +	MK_FLOW_ITEM(L2TPV2, sizeof(struct rte_flow_item_l2tpv2)),
>> +	MK_FLOW_ITEM(PPP, sizeof(struct rte_flow_item_ppp)),
>>   	MK_FLOW_ITEM(INTEGRITY, sizeof(struct rte_flow_item_integrity)),
>>   	MK_FLOW_ITEM(CONNTRACK, sizeof(uint32_t)),  }; diff --git
>> a/lib/ethdev/rte_flow.h b/lib/ethdev/rte_flow.h index
>> 70f455d47d..93205b7d1e 100644
>> --- a/lib/ethdev/rte_flow.h
>> +++ b/lib/ethdev/rte_flow.h
>> @@ -554,6 +554,20 @@ enum rte_flow_item_type {
>>   	 */
>>   	RTE_FLOW_ITEM_TYPE_GENEVE_OPT,
>>
>> +	/**
>> +	 * Matches L2TPV2 Header.
>> +	 *
>> +	 * See struct rte_flow_item_l2tpv2.
>> +	 */
>> +	RTE_FLOW_ITEM_TYPE_L2TPV2,
>> +
>> +	/**
>> +	 * Matches PPP Header.
>> +	 *
>> +	 * See struct rte_flow_item_ppp.
>> +	 */
>> +	RTE_FLOW_ITEM_TYPE_PPP,
>> +
> 
> Why did you push the new items here and not in the end?
> 
>>   	/**
>>   	 * [META]
>>   	 *
>> @@ -1799,6 +1813,91 @@ static const struct rte_flow_item_conntrack
>> rte_flow_item_conntrack_mask = {  };  #endif
>>
>> +/**
>> + * @warning
>> + * @b EXPERIMENTAL: this structure may change without prior notice
>> + * RTE_FLOW_ITEM_TYPE_L2TPV2
>> + *
>> + * Matches L2TPv2 Header
>> + */
>> +RTE_STD_C11
>> +struct rte_flow_item_l2tpv2 {
>> +	rte_be16_t flags_version;   /**< flag(12)  version(2). version must be
>> 2 */
>> +	union{
>> +		struct{
>> +			rte_be16_t length;  /**< length(16) */
>> +			rte_be16_t tunnel_id;   /**< tunnel id(16) */
>> +			rte_be16_t session_id;  /**< session id(16) */
>> +			rte_be32_t ns_nr;   /**< Ns(16) + Nr(16) */
> 
> Why not split those fields?
> 

Hi Ori,

As far as I remember the decision was to define protocol headers separately
and use them as first element in the flow_item struct, this enables casting
the flow_item to protocol. And Andrew did some cleanups in the past related
to this.
Can't we use the same logic for this case?

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

* Re: [dpdk-dev] [PATCH 3/4] ethdev: support PPPoL2TPv2oUDP RSS Hash
  2021-10-05 14:42     ` Ferruh Yigit
@ 2021-10-05 15:06       ` Ori Kam
  0 siblings, 0 replies; 71+ messages in thread
From: Ori Kam @ 2021-10-05 15:06 UTC (permalink / raw)
  To: Ferruh Yigit, Jie Wang, dev, andrew.rybchenko
  Cc: NBU-Contact-Thomas Monjalon, xiaoyun.li, jingjing.wu,
	beilei.xing, wenjun1.wu, stevex.yang



> -----Original Message-----
> From: Ferruh Yigit <ferruh.yigit@intel.com>
> Sent: Tuesday, October 5, 2021 5:43 PM
> To: Ori Kam <orika@nvidia.com>; Jie Wang <jie1x.wang@intel.com>;
> dev@dpdk.org; andrew.rybchenko@oktetlabs.ru
> Cc: NBU-Contact-Thomas Monjalon <thomas@monjalon.net>;
> xiaoyun.li@intel.com; jingjing.wu@intel.com; beilei.xing@intel.com;
> wenjun1.wu@intel.com; stevex.yang@intel.com
> Subject: Re: [dpdk-dev] [PATCH 3/4] ethdev: support PPPoL2TPv2oUDP RSS Hash
> 
> On 9/30/2021 3:38 PM, Ori Kam wrote:
> > Hi Jie,
> >
> > You are missing updating the rte_flow.rst and release notes:
> >
> > Please see more comments below.
> >
> > Thanks,
> > Ori
> >
> >> -----Original Message-----
> >> From: dev <dev-bounces@dpdk.org> On Behalf Of Jie Wang
> >> Sent: Friday, September 24, 2021 6:17 PM
> >> Subject: [dpdk-dev] [PATCH 3/4] ethdev: support PPPoL2TPv2oUDP RSS
> >> Hash
> >>
> >> Add flow pattern items, RSS offload types and header formats of
> >> L2TPv2 and PPP.
> >>
> >> Signed-off-by: Wenjun Wu <wenjun1.wu@intel.com>
> >> Signed-off-by: Jie Wang <jie1x.wang@intel.com>
> >> ---
> >>   lib/ethdev/rte_flow.c |  2 +
> >>   lib/ethdev/rte_flow.h | 99
> >> +++++++++++++++++++++++++++++++++++++++++++
> >>   2 files changed, 101 insertions(+)
> >>
> >> diff --git a/lib/ethdev/rte_flow.c b/lib/ethdev/rte_flow.c index
> >> 8cb7a069c8..307fbc3abe 100644
> >> --- a/lib/ethdev/rte_flow.c
> >> +++ b/lib/ethdev/rte_flow.c
> >> @@ -98,6 +98,8 @@ static const struct rte_flow_desc_data
> >> rte_flow_desc_item[] = {
> >>   	MK_FLOW_ITEM(PFCP, sizeof(struct rte_flow_item_pfcp)),
> >>   	MK_FLOW_ITEM(ECPRI, sizeof(struct rte_flow_item_ecpri)),
> >>   	MK_FLOW_ITEM(GENEVE_OPT, sizeof(struct
> rte_flow_item_geneve_opt)),
> >> +	MK_FLOW_ITEM(L2TPV2, sizeof(struct rte_flow_item_l2tpv2)),
> >> +	MK_FLOW_ITEM(PPP, sizeof(struct rte_flow_item_ppp)),
> >>   	MK_FLOW_ITEM(INTEGRITY, sizeof(struct rte_flow_item_integrity)),
> >>   	MK_FLOW_ITEM(CONNTRACK, sizeof(uint32_t)),  }; diff --git
> >> a/lib/ethdev/rte_flow.h b/lib/ethdev/rte_flow.h index
> >> 70f455d47d..93205b7d1e 100644
> >> --- a/lib/ethdev/rte_flow.h
> >> +++ b/lib/ethdev/rte_flow.h
> >> @@ -554,6 +554,20 @@ enum rte_flow_item_type {
> >>   	 */
> >>   	RTE_FLOW_ITEM_TYPE_GENEVE_OPT,
> >>
> >> +	/**
> >> +	 * Matches L2TPV2 Header.
> >> +	 *
> >> +	 * See struct rte_flow_item_l2tpv2.
> >> +	 */
> >> +	RTE_FLOW_ITEM_TYPE_L2TPV2,
> >> +
> >> +	/**
> >> +	 * Matches PPP Header.
> >> +	 *
> >> +	 * See struct rte_flow_item_ppp.
> >> +	 */
> >> +	RTE_FLOW_ITEM_TYPE_PPP,
> >> +
> >
> > Why did you push the new items here and not in the end?
> >
> >>   	/**
> >>   	 * [META]
> >>   	 *
> >> @@ -1799,6 +1813,91 @@ static const struct rte_flow_item_conntrack
> >> rte_flow_item_conntrack_mask = {  };  #endif
> >>
> >> +/**
> >> + * @warning
> >> + * @b EXPERIMENTAL: this structure may change without prior notice
> >> + * RTE_FLOW_ITEM_TYPE_L2TPV2
> >> + *
> >> + * Matches L2TPv2 Header
> >> + */
> >> +RTE_STD_C11
> >> +struct rte_flow_item_l2tpv2 {
> >> +	rte_be16_t flags_version;   /**< flag(12)  version(2). version must be
> >> 2 */
> >> +	union{
> >> +		struct{
> >> +			rte_be16_t length;  /**< length(16) */
> >> +			rte_be16_t tunnel_id;   /**< tunnel id(16) */
> >> +			rte_be16_t session_id;  /**< session id(16) */
> >> +			rte_be32_t ns_nr;   /**< Ns(16) + Nr(16) */
> >
> > Why not split those fields?
> >
> 
> Hi Ori,
> 
> As far as I remember the decision was to define protocol headers separately
> and use them as first element in the flow_item struct, this enables casting the
> flow_item to protocol. And Andrew did some cleanups in the past related to
> this.
> Can't we use the same logic for this case?

This is also my thinking but I'm not familiar with this protocol and it looks like it has many different
options.

Best,
Ori

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

* [dpdk-dev] [PATCH v2 0/3] support PPPoL2TPv2oUDP RSS Hash
  2021-09-24 15:17 [dpdk-dev] [PATCH 0/4] support PPPoL2TPv2oUDP RSS Hash Jie Wang
                   ` (3 preceding siblings ...)
  2021-09-24 15:17 ` [dpdk-dev] [PATCH 4/4] net/iavf: support PPPoL2TPv2oUDP over IPv6 " Jie Wang
@ 2021-10-12 10:25 ` Jie Wang
  2021-10-12 10:25   ` [dpdk-dev] [PATCH v2 1/3] net/iavf: " Jie Wang
                     ` (3 more replies)
  4 siblings, 4 replies; 71+ messages in thread
From: Jie Wang @ 2021-10-12 10:25 UTC (permalink / raw)
  To: dev
  Cc: ferruh.yigit, thomas, andrew.rybchenko, xiaoyun.li, stevex.yang,
	jingjing.wu, beilei.xing, wenjun1.wu, Jie Wang

Support IAVF PPPoL2TPv2oUDP RSS Hash. Required to distribute packets
based on inner IP src+dest address and TCP/UDP src+dest port.

---
v2:
 * update the rte_flow.rst and release notes.
 * update l2tpv2 header format.

Jie Wang (3):
  net/iavf: support PPPoL2TPv2oUDP RSS Hash
  app/testpmd: support PPPoL2TPv2oUDP RSS Hash
  ethdev: support PPPoL2TPv2oUDP RSS Hash

 app/test-pmd/cmdline_flow.c            |  34 ++++
 doc/guides/prog_guide/rte_flow.rst     |  25 +++
 doc/guides/rel_notes/release_21_11.rst |   5 +
 drivers/net/iavf/iavf_generic_flow.c   | 131 +++++++++++++++
 drivers/net/iavf/iavf_generic_flow.h   |  15 ++
 drivers/net/iavf/iavf_hash.c           | 108 ++++++++++++-
 lib/ethdev/rte_flow.c                  |   2 +
 lib/ethdev/rte_flow.h                  |  65 ++++++++
 lib/net/rte_l2tpv2.h                   | 214 +++++++++++++++++++++++++
 9 files changed, 597 insertions(+), 2 deletions(-)
 create mode 100644 lib/net/rte_l2tpv2.h

-- 
2.25.1


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

* [dpdk-dev] [PATCH v2 1/3] net/iavf: support PPPoL2TPv2oUDP RSS Hash
  2021-10-12 10:25 ` [dpdk-dev] [PATCH v2 0/3] support PPPoL2TPv2oUDP " Jie Wang
@ 2021-10-12 10:25   ` Jie Wang
  2021-10-12 10:25   ` [dpdk-dev] [PATCH v2 2/3] app/testpmd: " Jie Wang
                     ` (2 subsequent siblings)
  3 siblings, 0 replies; 71+ messages in thread
From: Jie Wang @ 2021-10-12 10:25 UTC (permalink / raw)
  To: dev
  Cc: ferruh.yigit, thomas, andrew.rybchenko, xiaoyun.li, stevex.yang,
	jingjing.wu, beilei.xing, wenjun1.wu, Jie Wang

Add support for PPP over L2TPv2 over UDP protocol RSS Hash based
on inner IP src/dst address and TCP/UDP src/dst port.

Patterns are listed below:
eth/ipv4(6)/udp/l2tpv2/ppp/ipv4(6)
eth/ipv4(6)/udp/l2tpv2/ppp/ipv4(6)/udp
eth/ipv4(6)/udp/l2tpv2/ppp/ipv4(6)/tcp

Signed-off-by: Wenjun Wu <wenjun1.wu@intel.com>
Signed-off-by: Jie Wang <jie1x.wang@intel.com>
---
 drivers/net/iavf/iavf_generic_flow.c | 131 +++++++++++++++++++++++++++
 drivers/net/iavf/iavf_generic_flow.h |  15 +++
 drivers/net/iavf/iavf_hash.c         | 108 +++++++++++++++++++++-
 3 files changed, 252 insertions(+), 2 deletions(-)

diff --git a/drivers/net/iavf/iavf_generic_flow.c b/drivers/net/iavf/iavf_generic_flow.c
index b86d99e57d..364904fa02 100644
--- a/drivers/net/iavf/iavf_generic_flow.c
+++ b/drivers/net/iavf/iavf_generic_flow.c
@@ -1611,6 +1611,137 @@ enum rte_flow_item_type iavf_pattern_eth_ipv6_gre_ipv6_udp[] = {
 	RTE_FLOW_ITEM_TYPE_END,
 };
 
+/* PPPoL2TPv2oUDP */
+enum rte_flow_item_type iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv4[] = {
+	RTE_FLOW_ITEM_TYPE_ETH,
+	RTE_FLOW_ITEM_TYPE_IPV4,
+	RTE_FLOW_ITEM_TYPE_UDP,
+	RTE_FLOW_ITEM_TYPE_L2TPV2,
+	RTE_FLOW_ITEM_TYPE_PPP,
+	RTE_FLOW_ITEM_TYPE_IPV4,
+	RTE_FLOW_ITEM_TYPE_END,
+};
+
+enum rte_flow_item_type iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv6[] = {
+	RTE_FLOW_ITEM_TYPE_ETH,
+	RTE_FLOW_ITEM_TYPE_IPV4,
+	RTE_FLOW_ITEM_TYPE_UDP,
+	RTE_FLOW_ITEM_TYPE_L2TPV2,
+	RTE_FLOW_ITEM_TYPE_PPP,
+	RTE_FLOW_ITEM_TYPE_IPV6,
+	RTE_FLOW_ITEM_TYPE_END,
+};
+
+enum rte_flow_item_type iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv4_udp[] = {
+	RTE_FLOW_ITEM_TYPE_ETH,
+	RTE_FLOW_ITEM_TYPE_IPV4,
+	RTE_FLOW_ITEM_TYPE_UDP,
+	RTE_FLOW_ITEM_TYPE_L2TPV2,
+	RTE_FLOW_ITEM_TYPE_PPP,
+	RTE_FLOW_ITEM_TYPE_IPV4,
+	RTE_FLOW_ITEM_TYPE_UDP,
+	RTE_FLOW_ITEM_TYPE_END,
+};
+
+enum rte_flow_item_type iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv4_tcp[] = {
+	RTE_FLOW_ITEM_TYPE_ETH,
+	RTE_FLOW_ITEM_TYPE_IPV4,
+	RTE_FLOW_ITEM_TYPE_UDP,
+	RTE_FLOW_ITEM_TYPE_L2TPV2,
+	RTE_FLOW_ITEM_TYPE_PPP,
+	RTE_FLOW_ITEM_TYPE_IPV4,
+	RTE_FLOW_ITEM_TYPE_TCP,
+	RTE_FLOW_ITEM_TYPE_END,
+};
+
+enum rte_flow_item_type iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv6_udp[] = {
+	RTE_FLOW_ITEM_TYPE_ETH,
+	RTE_FLOW_ITEM_TYPE_IPV4,
+	RTE_FLOW_ITEM_TYPE_UDP,
+	RTE_FLOW_ITEM_TYPE_L2TPV2,
+	RTE_FLOW_ITEM_TYPE_PPP,
+	RTE_FLOW_ITEM_TYPE_IPV6,
+	RTE_FLOW_ITEM_TYPE_UDP,
+	RTE_FLOW_ITEM_TYPE_END,
+};
+
+enum rte_flow_item_type iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv6_tcp[] = {
+	RTE_FLOW_ITEM_TYPE_ETH,
+	RTE_FLOW_ITEM_TYPE_IPV4,
+	RTE_FLOW_ITEM_TYPE_UDP,
+	RTE_FLOW_ITEM_TYPE_L2TPV2,
+	RTE_FLOW_ITEM_TYPE_PPP,
+	RTE_FLOW_ITEM_TYPE_IPV6,
+	RTE_FLOW_ITEM_TYPE_TCP,
+	RTE_FLOW_ITEM_TYPE_END,
+};
+
+enum rte_flow_item_type iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv4[] = {
+	RTE_FLOW_ITEM_TYPE_ETH,
+	RTE_FLOW_ITEM_TYPE_IPV6,
+	RTE_FLOW_ITEM_TYPE_UDP,
+	RTE_FLOW_ITEM_TYPE_L2TPV2,
+	RTE_FLOW_ITEM_TYPE_PPP,
+	RTE_FLOW_ITEM_TYPE_IPV4,
+	RTE_FLOW_ITEM_TYPE_END,
+};
+
+enum rte_flow_item_type iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv6[] = {
+	RTE_FLOW_ITEM_TYPE_ETH,
+	RTE_FLOW_ITEM_TYPE_IPV6,
+	RTE_FLOW_ITEM_TYPE_UDP,
+	RTE_FLOW_ITEM_TYPE_L2TPV2,
+	RTE_FLOW_ITEM_TYPE_PPP,
+	RTE_FLOW_ITEM_TYPE_IPV6,
+	RTE_FLOW_ITEM_TYPE_END,
+};
+
+enum rte_flow_item_type iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv4_udp[] = {
+	RTE_FLOW_ITEM_TYPE_ETH,
+	RTE_FLOW_ITEM_TYPE_IPV6,
+	RTE_FLOW_ITEM_TYPE_UDP,
+	RTE_FLOW_ITEM_TYPE_L2TPV2,
+	RTE_FLOW_ITEM_TYPE_PPP,
+	RTE_FLOW_ITEM_TYPE_IPV4,
+	RTE_FLOW_ITEM_TYPE_UDP,
+	RTE_FLOW_ITEM_TYPE_END,
+};
+
+enum rte_flow_item_type iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv4_tcp[] = {
+	RTE_FLOW_ITEM_TYPE_ETH,
+	RTE_FLOW_ITEM_TYPE_IPV6,
+	RTE_FLOW_ITEM_TYPE_UDP,
+	RTE_FLOW_ITEM_TYPE_L2TPV2,
+	RTE_FLOW_ITEM_TYPE_PPP,
+	RTE_FLOW_ITEM_TYPE_IPV4,
+	RTE_FLOW_ITEM_TYPE_TCP,
+	RTE_FLOW_ITEM_TYPE_END,
+};
+
+enum rte_flow_item_type iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv6_udp[] = {
+	RTE_FLOW_ITEM_TYPE_ETH,
+	RTE_FLOW_ITEM_TYPE_IPV6,
+	RTE_FLOW_ITEM_TYPE_UDP,
+	RTE_FLOW_ITEM_TYPE_L2TPV2,
+	RTE_FLOW_ITEM_TYPE_PPP,
+	RTE_FLOW_ITEM_TYPE_IPV6,
+	RTE_FLOW_ITEM_TYPE_UDP,
+	RTE_FLOW_ITEM_TYPE_END,
+};
+
+enum rte_flow_item_type iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv6_tcp[] = {
+	RTE_FLOW_ITEM_TYPE_ETH,
+	RTE_FLOW_ITEM_TYPE_IPV6,
+	RTE_FLOW_ITEM_TYPE_UDP,
+	RTE_FLOW_ITEM_TYPE_L2TPV2,
+	RTE_FLOW_ITEM_TYPE_PPP,
+	RTE_FLOW_ITEM_TYPE_IPV6,
+	RTE_FLOW_ITEM_TYPE_TCP,
+	RTE_FLOW_ITEM_TYPE_END,
+};
+
+
+
 typedef struct iavf_flow_engine * (*parse_engine_t)(struct iavf_adapter *ad,
 		struct rte_flow *flow,
 		struct iavf_parser_list *parser_list,
diff --git a/drivers/net/iavf/iavf_generic_flow.h b/drivers/net/iavf/iavf_generic_flow.h
index 4794d1fb80..f2b54e1944 100644
--- a/drivers/net/iavf/iavf_generic_flow.h
+++ b/drivers/net/iavf/iavf_generic_flow.h
@@ -410,6 +410,21 @@ extern enum rte_flow_item_type iavf_pattern_eth_ipv6_gre_ipv6_tcp[];
 extern enum rte_flow_item_type iavf_pattern_eth_ipv6_gre_ipv4_udp[];
 extern enum rte_flow_item_type iavf_pattern_eth_ipv6_gre_ipv6_udp[];
 
+/* PPPoL2TPv2oUDP */
+extern enum rte_flow_item_type iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv4[];
+extern enum rte_flow_item_type iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv6[];
+extern enum rte_flow_item_type iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv4_udp[];
+extern enum rte_flow_item_type iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv4_tcp[];
+extern enum rte_flow_item_type iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv6_udp[];
+extern enum rte_flow_item_type iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv6_tcp[];
+extern enum rte_flow_item_type iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv4[];
+extern enum rte_flow_item_type iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv6[];
+extern enum rte_flow_item_type iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv4_udp[];
+extern enum rte_flow_item_type iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv4_tcp[];
+extern enum rte_flow_item_type iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv6_udp[];
+extern enum rte_flow_item_type iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv6_tcp[];
+
+
 extern const struct rte_flow_ops iavf_flow_ops;
 
 /* pattern structure */
diff --git a/drivers/net/iavf/iavf_hash.c b/drivers/net/iavf/iavf_hash.c
index 1f2d3772d1..9e7286861e 100644
--- a/drivers/net/iavf/iavf_hash.c
+++ b/drivers/net/iavf/iavf_hash.c
@@ -34,6 +34,8 @@
 /* the second IP header of GTPoGRE */
 #define IAVF_PHINT_MID_IPV4			BIT_ULL(7)
 #define IAVF_PHINT_MID_IPV6			BIT_ULL(8)
+/* L2TPV2 */
+#define IAVF_PHINT_L2TPV2			BIT_ULL(9)
 
 #define IAVF_PHINT_GTPU_MSK	(IAVF_PHINT_GTPU	| \
 				 IAVF_PHINT_GTPU_EH	| \
@@ -164,6 +166,12 @@ iavf_hash_parse_pattern_action(struct iavf_adapter *ad,
 	VIRTCHNL_PROTO_HDR_ECPRI, \
 	FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_ECPRI_PC_RTC_ID), {BUFF_NOUSED} }
 
+#define proto_hdr_l2tpv2 { \
+	VIRTCHNL_PROTO_HDR_L2TPV2, 0, {BUFF_NOUSED} }
+
+#define proto_hdr_ppp { \
+	VIRTCHNL_PROTO_HDR_PPP, 0, {BUFF_NOUSED} }
+
 #define TUNNEL_LEVEL_OUTER		0
 #define TUNNEL_LEVEL_INNER		1
 
@@ -338,6 +346,52 @@ struct virtchnl_proto_hdrs ipv4_ecpri_tmplt = {
 	TUNNEL_LEVEL_OUTER, 3, {proto_hdr_ipv4, proto_hdr_udp, proto_hdr_ecpri}
 };
 
+struct virtchnl_proto_hdrs udp_l2tpv2_ppp_ipv4_tmplt = {
+	TUNNEL_LEVEL_INNER, 3,
+	{proto_hdr_l2tpv2,
+	 proto_hdr_ppp,
+	 proto_hdr_ipv4}
+};
+
+struct virtchnl_proto_hdrs udp_l2tpv2_ppp_ipv6_tmplt = {
+	TUNNEL_LEVEL_INNER, 3,
+	{proto_hdr_l2tpv2,
+	 proto_hdr_ppp,
+	 proto_hdr_ipv6}
+};
+
+struct virtchnl_proto_hdrs udp_l2tpv2_ppp_ipv4_udp_tmplt = {
+	TUNNEL_LEVEL_INNER, 4,
+	{proto_hdr_l2tpv2,
+	 proto_hdr_ppp,
+	 proto_hdr_ipv4_with_prot,
+	 proto_hdr_udp}
+};
+
+struct virtchnl_proto_hdrs udp_l2tpv2_ppp_ipv4_tcp_tmplt = {
+	TUNNEL_LEVEL_INNER, 4,
+	{proto_hdr_l2tpv2,
+	 proto_hdr_ppp,
+	 proto_hdr_ipv4_with_prot,
+	 proto_hdr_tcp}
+};
+
+struct virtchnl_proto_hdrs udp_l2tpv2_ppp_ipv6_udp_tmplt = {
+	TUNNEL_LEVEL_INNER, 4,
+	{proto_hdr_l2tpv2,
+	 proto_hdr_ppp,
+	 proto_hdr_ipv6_with_prot,
+	 proto_hdr_udp}
+};
+
+struct virtchnl_proto_hdrs udp_l2tpv2_ppp_ipv6_tcp_tmplt = {
+	TUNNEL_LEVEL_INNER, 4,
+	{proto_hdr_l2tpv2,
+	 proto_hdr_ppp,
+	 proto_hdr_ipv6_with_prot,
+	 proto_hdr_tcp}
+};
+
 /* rss type super set */
 
 /* IPv4 outer */
@@ -493,6 +547,13 @@ static struct iavf_pattern_match_item iavf_hash_pattern_list[] = {
 	{iavf_pattern_eth_ipv6_gre_ipv4_tcp,	IAVF_RSS_TYPE_INNER_IPV4_TCP, &inner_ipv4_tcp_tmplt},
 	{iavf_pattern_eth_ipv4_gre_ipv4_udp,	IAVF_RSS_TYPE_INNER_IPV4_UDP, &inner_ipv4_udp_tmplt},
 	{iavf_pattern_eth_ipv6_gre_ipv4_udp,	IAVF_RSS_TYPE_INNER_IPV4_UDP, &inner_ipv4_udp_tmplt},
+	{iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv4,	IAVF_RSS_TYPE_INNER_IPV4,	&udp_l2tpv2_ppp_ipv4_tmplt},
+	{iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv4_udp,	IAVF_RSS_TYPE_INNER_IPV4_UDP,	&udp_l2tpv2_ppp_ipv4_udp_tmplt},
+	{iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv4_tcp,	IAVF_RSS_TYPE_INNER_IPV4_TCP,	&udp_l2tpv2_ppp_ipv4_tcp_tmplt},
+	{iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv4,	IAVF_RSS_TYPE_INNER_IPV4,	&udp_l2tpv2_ppp_ipv4_tmplt},
+	{iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv4_udp,	IAVF_RSS_TYPE_INNER_IPV4_UDP,	&udp_l2tpv2_ppp_ipv4_udp_tmplt},
+	{iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv4_tcp,	IAVF_RSS_TYPE_INNER_IPV4_TCP,	&udp_l2tpv2_ppp_ipv4_tcp_tmplt},
+
 	/* IPv6 */
 	{iavf_pattern_eth_ipv6,				IAVF_RSS_TYPE_OUTER_IPV6,	&outer_ipv6_tmplt},
 	{iavf_pattern_eth_ipv6_frag_ext,		IAVF_RSS_TYPE_OUTER_IPV6_FRAG,	&outer_ipv6_frag_tmplt},
@@ -553,6 +614,13 @@ static struct iavf_pattern_match_item iavf_hash_pattern_list[] = {
 	{iavf_pattern_eth_ipv6_gre_ipv6_tcp,	IAVF_RSS_TYPE_INNER_IPV6_TCP, &inner_ipv6_tcp_tmplt},
 	{iavf_pattern_eth_ipv4_gre_ipv6_udp,	IAVF_RSS_TYPE_INNER_IPV6_UDP, &inner_ipv6_udp_tmplt},
 	{iavf_pattern_eth_ipv6_gre_ipv6_udp,	IAVF_RSS_TYPE_INNER_IPV6_UDP, &inner_ipv6_udp_tmplt},
+	{iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv6,	IAVF_RSS_TYPE_INNER_IPV6,	&udp_l2tpv2_ppp_ipv6_tmplt},
+	{iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv6_udp,	IAVF_RSS_TYPE_INNER_IPV6_UDP,	&udp_l2tpv2_ppp_ipv6_udp_tmplt},
+	{iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv6_tcp,	IAVF_RSS_TYPE_INNER_IPV6_TCP,	&udp_l2tpv2_ppp_ipv6_tcp_tmplt},
+	{iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv6,	IAVF_RSS_TYPE_INNER_IPV6,	&udp_l2tpv2_ppp_ipv6_tmplt},
+	{iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv6_udp,	IAVF_RSS_TYPE_INNER_IPV6_UDP,	&udp_l2tpv2_ppp_ipv6_udp_tmplt},
+	{iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv6_tcp,	IAVF_RSS_TYPE_INNER_IPV6_TCP,	&udp_l2tpv2_ppp_ipv6_tcp_tmplt},
+
 };
 
 static struct iavf_flow_engine iavf_hash_engine = {
@@ -687,13 +755,17 @@ iavf_hash_parse_pattern(const struct rte_flow_item pattern[], uint64_t *phint,
 
 		switch (item->type) {
 		case RTE_FLOW_ITEM_TYPE_IPV4:
-			if (!(*phint & IAVF_PHINT_GTPU_MSK) && !(*phint & IAVF_PHINT_GRE))
+			if (!(*phint & IAVF_PHINT_GTPU_MSK) &&
+			    !(*phint & IAVF_PHINT_GRE) &&
+			    !(*phint & IAVF_PHINT_L2TPV2))
 				*phint |= IAVF_PHINT_OUTER_IPV4;
 			if ((*phint & IAVF_PHINT_GRE) && !(*phint & IAVF_PHINT_GTPU_MSK))
 				*phint |= IAVF_PHINT_MID_IPV4;
 			break;
 		case RTE_FLOW_ITEM_TYPE_IPV6:
-			if (!(*phint & IAVF_PHINT_GTPU_MSK) && !(*phint & IAVF_PHINT_GRE))
+			if (!(*phint & IAVF_PHINT_GTPU_MSK) &&
+			    !(*phint & IAVF_PHINT_GRE) &&
+			    !(*phint & IAVF_PHINT_L2TPV2))
 				*phint |= IAVF_PHINT_OUTER_IPV6;
 			if ((*phint & IAVF_PHINT_GRE) && !(*phint & IAVF_PHINT_GTPU_MSK))
 				*phint |= IAVF_PHINT_MID_IPV6;
@@ -728,6 +800,10 @@ iavf_hash_parse_pattern(const struct rte_flow_item pattern[], uint64_t *phint,
 			break;
 		case RTE_FLOW_ITEM_TYPE_GRE:
 			*phint |= IAVF_PHINT_GRE;
+			break;
+		case RTE_FLOW_ITEM_TYPE_L2TPV2:
+			*phint |= IAVF_PHINT_L2TPV2;
+			break;
 		default:
 			break;
 		}
@@ -1050,12 +1126,40 @@ iavf_refine_proto_hdrs_by_pattern(struct virtchnl_proto_hdrs *proto_hdrs,
 	proto_hdrs->tunnel_level = tun_lvl;
 }
 
+static void
+iavf_refine_proto_hdrs_l2tpv2(struct virtchnl_proto_hdrs *proto_hdrs,
+			      uint64_t phint)
+{
+	struct virtchnl_proto_hdr *hdr1;
+	int i;
+
+	if (!(phint & IAVF_PHINT_L2TPV2))
+		return;
+
+	if (proto_hdrs->tunnel_level == TUNNEL_LEVEL_INNER) {
+		/* shift headers layer */
+		for (i = proto_hdrs->count - 1 + 1; i > 0; i--)
+			proto_hdrs->proto_hdr[i] = proto_hdrs->proto_hdr[i - 1];
+
+		/* adding outer ip header at layer 0 */
+		hdr1 = &proto_hdrs->proto_hdr[0];
+		hdr1->field_selector = 0;
+		proto_hdrs->count++;
+		proto_hdrs->tunnel_level = TUNNEL_LEVEL_OUTER;
+		if (phint & IAVF_PHINT_OUTER_IPV4)
+			VIRTCHNL_SET_PROTO_HDR_TYPE(hdr1, IPV4);
+		else if (phint & IAVF_PHINT_OUTER_IPV6)
+			VIRTCHNL_SET_PROTO_HDR_TYPE(hdr1, IPV6);
+	}
+}
+
 static void iavf_refine_proto_hdrs(struct virtchnl_proto_hdrs *proto_hdrs,
 				   uint64_t rss_type, uint64_t phint)
 {
 	iavf_refine_proto_hdrs_l234(proto_hdrs, rss_type);
 	iavf_refine_proto_hdrs_by_pattern(proto_hdrs, phint);
 	iavf_refine_proto_hdrs_gtpu(proto_hdrs, rss_type);
+	iavf_refine_proto_hdrs_l2tpv2(proto_hdrs, phint);
 }
 
 static uint64_t invalid_rss_comb[] = {
-- 
2.25.1


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

* [dpdk-dev] [PATCH v2 2/3] app/testpmd: support PPPoL2TPv2oUDP RSS Hash
  2021-10-12 10:25 ` [dpdk-dev] [PATCH v2 0/3] support PPPoL2TPv2oUDP " Jie Wang
  2021-10-12 10:25   ` [dpdk-dev] [PATCH v2 1/3] net/iavf: " Jie Wang
@ 2021-10-12 10:25   ` Jie Wang
  2021-10-12 15:31     ` Ori Kam
  2021-10-12 10:25   ` [dpdk-dev] [PATCH v2 3/3] ethdev: " Jie Wang
  2021-10-15  9:58   ` [dpdk-dev] [PATCH v3 0/3] " Jie Wang
  3 siblings, 1 reply; 71+ messages in thread
From: Jie Wang @ 2021-10-12 10:25 UTC (permalink / raw)
  To: dev
  Cc: ferruh.yigit, thomas, andrew.rybchenko, xiaoyun.li, stevex.yang,
	jingjing.wu, beilei.xing, wenjun1.wu, Jie Wang

Add support for test-pmd to parse protocol pattern L2TPv2 and PPP.

Signed-off-by: Wenjun Wu <wenjun1.wu@intel.com>
Signed-off-by: Jie Wang <jie1x.wang@intel.com>
---
 app/test-pmd/cmdline_flow.c | 34 ++++++++++++++++++++++++++++++++++
 1 file changed, 34 insertions(+)

diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
index bb22294dd3..3c9bcabd97 100644
--- a/app/test-pmd/cmdline_flow.c
+++ b/app/test-pmd/cmdline_flow.c
@@ -299,6 +299,8 @@ enum index {
 	ITEM_GENEVE_OPT_TYPE,
 	ITEM_GENEVE_OPT_LENGTH,
 	ITEM_GENEVE_OPT_DATA,
+	ITEM_PPP,
+	ITEM_L2TPV2,
 	ITEM_INTEGRITY,
 	ITEM_INTEGRITY_LEVEL,
 	ITEM_INTEGRITY_VALUE,
@@ -997,6 +999,8 @@ static const enum index next_item[] = {
 	ITEM_AH,
 	ITEM_PFCP,
 	ITEM_ECPRI,
+	ITEM_PPP,
+	ITEM_L2TPV2,
 	ITEM_GENEVE_OPT,
 	ITEM_INTEGRITY,
 	ITEM_CONNTRACK,
@@ -1368,6 +1372,16 @@ static const enum index item_integrity_lv[] = {
 	ZERO,
 };
 
+static const enum index item_ppp[] = {
+	ITEM_NEXT,
+	ZERO,
+};
+
+static const enum index item_l2tpv2[] = {
+	ITEM_NEXT,
+	ZERO,
+};
+
 static const enum index next_action[] = {
 	ACTION_END,
 	ACTION_VOID,
@@ -3579,6 +3593,20 @@ static const struct token token_list[] = {
 				(sizeof(struct rte_flow_item_geneve_opt),
 				ITEM_GENEVE_OPT_DATA_SIZE)),
 	},
+	[ITEM_PPP] = {
+		.name = "ppp",
+		.help = "match ppp header",
+		.priv = PRIV_ITEM(PPP, sizeof(struct rte_flow_item_ppp)),
+		.next = NEXT(item_ppp),
+		.call = parse_vc,
+	},
+	[ITEM_L2TPV2] = {
+		.name = "l2tpv2",
+		.help = "match l2tpv2 header",
+		.priv = PRIV_ITEM(L2TPV2, sizeof(struct rte_flow_item_l2tpv2)),
+		.next = NEXT(item_l2tpv2),
+		.call = parse_vc,
+	},
 	[ITEM_INTEGRITY] = {
 		.name = "integrity",
 		.help = "match packet integrity",
@@ -8343,6 +8371,12 @@ flow_item_default_mask(const struct rte_flow_item *item)
 	case RTE_FLOW_ITEM_TYPE_PFCP:
 		mask = &rte_flow_item_pfcp_mask;
 		break;
+	case RTE_FLOW_ITEM_TYPE_L2TPV2:
+		mask = &rte_flow_item_l2tpv2_mask;
+		break;
+	case RTE_FLOW_ITEM_TYPE_PPP:
+		mask = &rte_flow_item_ppp_mask;
+		break;
 	default:
 		break;
 	}
-- 
2.25.1


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

* [dpdk-dev] [PATCH v2 3/3] ethdev: support PPPoL2TPv2oUDP RSS Hash
  2021-10-12 10:25 ` [dpdk-dev] [PATCH v2 0/3] support PPPoL2TPv2oUDP " Jie Wang
  2021-10-12 10:25   ` [dpdk-dev] [PATCH v2 1/3] net/iavf: " Jie Wang
  2021-10-12 10:25   ` [dpdk-dev] [PATCH v2 2/3] app/testpmd: " Jie Wang
@ 2021-10-12 10:25   ` Jie Wang
  2021-10-12 15:28     ` Ori Kam
  2021-10-15  9:58   ` [dpdk-dev] [PATCH v3 0/3] " Jie Wang
  3 siblings, 1 reply; 71+ messages in thread
From: Jie Wang @ 2021-10-12 10:25 UTC (permalink / raw)
  To: dev
  Cc: ferruh.yigit, thomas, andrew.rybchenko, xiaoyun.li, stevex.yang,
	jingjing.wu, beilei.xing, wenjun1.wu, Jie Wang

Added flow pattern items and header formats of L2TPv2 and PPP to
support PPP over L2TPv2 over UDP protocol RSS Hash.

Signed-off-by: Wenjun Wu <wenjun1.wu@intel.com>
Signed-off-by: Jie Wang <jie1x.wang@intel.com>
---
 doc/guides/prog_guide/rte_flow.rst     |  25 +++
 doc/guides/rel_notes/release_21_11.rst |   5 +
 lib/ethdev/rte_flow.c                  |   2 +
 lib/ethdev/rte_flow.h                  |  65 ++++++++
 lib/net/rte_l2tpv2.h                   | 214 +++++++++++++++++++++++++
 5 files changed, 311 insertions(+)
 create mode 100644 lib/net/rte_l2tpv2.h

diff --git a/doc/guides/prog_guide/rte_flow.rst b/doc/guides/prog_guide/rte_flow.rst
index 2b42d5ec8c..e161fa8620 100644
--- a/doc/guides/prog_guide/rte_flow.rst
+++ b/doc/guides/prog_guide/rte_flow.rst
@@ -1425,6 +1425,31 @@ Matches a conntrack state after conntrack action.
 - ``flags``: conntrack packet state flags.
 - Default ``mask`` matches all state bits.
 
+Item: ``L2TPV2``
+^^^^^^^^^^^^^^^^^^^
+
+Matches a L2TPv2 header.
+
+- ``flags_version``: flags(12b), version(4b).
+- ``length``: total length of the message.
+- ``tunnel_id``: identifier for the control connection.
+- ``session_id``: identifier for a session within a tunnel.
+- ``ns``: sequence number for this date or control message.
+- ``nr``: sequence number expected in the next control message to be received.
+- ``offset_size``: offset of payload data.
+- ``offset_padding``: offset padding, variable length.
+- Default ``mask`` matches flags_version only.
+
+Item: ``PPP``
+^^^^^^^^^^^^^^^^^^^
+
+Matches a PPP header.
+
+- ``addr``: ppp address.
+- ``ctrl``: ppp control.
+- ``proto_id``: ppp protocol identifier.
+- Default ``mask`` matches addr, ctrl, proto_id.
+
 Actions
 ~~~~~~~
 
diff --git a/doc/guides/rel_notes/release_21_11.rst b/doc/guides/rel_notes/release_21_11.rst
index 93082723cf..af8e0733db 100644
--- a/doc/guides/rel_notes/release_21_11.rst
+++ b/doc/guides/rel_notes/release_21_11.rst
@@ -67,6 +67,11 @@ New Features
   Added macros ETH_RSS_IPV4_CHKSUM and ETH_RSS_L4_CHKSUM, now IPv4 and
   TCP/UDP/SCTP header checksum field can be used as input set for RSS.
 
+* **Added L2TPV2 and PPP protocol support in rte_flow.**
+
+  Added flow pattern items and header formats of L2TPv2 and PPP to support
+  PPP over L2TPv2 over UDP protocol RSS Hash.
+
 * **Updated Broadcom bnxt PMD.**
 
   * Added flow offload support for Thor.
diff --git a/lib/ethdev/rte_flow.c b/lib/ethdev/rte_flow.c
index 8cb7a069c8..307fbc3abe 100644
--- a/lib/ethdev/rte_flow.c
+++ b/lib/ethdev/rte_flow.c
@@ -98,6 +98,8 @@ static const struct rte_flow_desc_data rte_flow_desc_item[] = {
 	MK_FLOW_ITEM(PFCP, sizeof(struct rte_flow_item_pfcp)),
 	MK_FLOW_ITEM(ECPRI, sizeof(struct rte_flow_item_ecpri)),
 	MK_FLOW_ITEM(GENEVE_OPT, sizeof(struct rte_flow_item_geneve_opt)),
+	MK_FLOW_ITEM(L2TPV2, sizeof(struct rte_flow_item_l2tpv2)),
+	MK_FLOW_ITEM(PPP, sizeof(struct rte_flow_item_ppp)),
 	MK_FLOW_ITEM(INTEGRITY, sizeof(struct rte_flow_item_integrity)),
 	MK_FLOW_ITEM(CONNTRACK, sizeof(uint32_t)),
 };
diff --git a/lib/ethdev/rte_flow.h b/lib/ethdev/rte_flow.h
index 7b1ed7f110..a7a7bd983b 100644
--- a/lib/ethdev/rte_flow.h
+++ b/lib/ethdev/rte_flow.h
@@ -35,6 +35,7 @@
 #include <rte_mbuf_dyn.h>
 #include <rte_meter.h>
 #include <rte_gtp.h>
+#include <rte_l2tpv2.h>
 
 #ifdef __cplusplus
 extern "C" {
@@ -574,6 +575,21 @@ enum rte_flow_item_type {
 	 * @see struct rte_flow_item_conntrack.
 	 */
 	RTE_FLOW_ITEM_TYPE_CONNTRACK,
+
+	/**
+	 * Matches L2TPV2 Header.
+	 *
+	 * See struct rte_flow_item_l2tpv2.
+	 */
+	RTE_FLOW_ITEM_TYPE_L2TPV2,
+
+	/**
+	 * Matches PPP Header.
+	 *
+	 * See struct rte_flow_item_ppp.
+	 */
+	RTE_FLOW_ITEM_TYPE_PPP,
+
 };
 
 /**
@@ -1799,6 +1815,55 @@ static const struct rte_flow_item_conntrack rte_flow_item_conntrack_mask = {
 };
 #endif
 
+/**
+ * @warning
+ * @b EXPERIMENTAL: this structure may change without prior notice
+ * RTE_FLOW_ITEM_TYPE_L2TPV2
+ *
+ * Matches L2TPv2 Header
+ */
+struct rte_flow_item_l2tpv2 {
+	struct rte_l2tpv2_combined_msg_hdr hdr;
+};
+
+/** Default mask for RTE_FLOW_ITEM_TYPE_L2TPV2. */
+#ifndef __cplusplus
+static const struct rte_flow_item_l2tpv2 rte_flow_item_l2tpv2_mask = {
+	/*
+	 * flags and version bit mask
+	 * 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0
+	 * T L x x S x O P x x x x V V V V
+	 */
+	.hdr = {
+		.common = {
+			.flags_version = 0xcb0f,
+		},
+	},
+};
+#endif
+
+/**
+ * @warning
+ * @b EXPERIMENTAL: this structure may change without prior notice
+ * RTE_FLOW_ITEM_TYPE_PPP
+ *
+ * Matches PPP Header
+ */
+struct rte_flow_item_ppp {
+	uint8_t addr; /**< ppp address(8) */
+	uint8_t ctrl; /**< ppp control(8) */
+	rte_be16_t proto_id; /**< ppp protocol id(16) */
+};
+
+/** Default mask for RTE_FLOW_ITEM_TYPE_PPP. */
+#ifndef __cplusplus
+static const struct rte_flow_item_ppp rte_flow_item_ppp_mask = {
+	.addr = 0xff,
+	.ctrl = 0xff,
+	.proto_id = 0xffff,
+};
+#endif
+
 /**
  * Matching pattern item definition.
  *
diff --git a/lib/net/rte_l2tpv2.h b/lib/net/rte_l2tpv2.h
new file mode 100644
index 0000000000..aea3c689be
--- /dev/null
+++ b/lib/net/rte_l2tpv2.h
@@ -0,0 +1,214 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright 2021 Mellanox Technologies, Ltd
+ */
+
+#ifndef _RTE_L2TPV2_H_
+#define _RTE_L2TPV2_H_
+
+/**
+ * @file
+ *
+ * L2TP header:
+ *  0                   1                   2                   3
+ *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |T|L|x|x|S|x|O|P|x|x|x|x|  Ver  |          Length (opt)         |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |           Tunnel ID           |           Session ID          |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |             Ns (opt)          |             Nr (opt)          |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |      Offset Size (opt)        |    Offset pad... (opt)
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *
+ * The Type (T) bit indicates the type of message. It is set to 0 for a data
+ * message and 1 for a control message.
+ *
+ * If the Length (L) bit is 1, the Length field is present. This bit MUST be
+ * set to 1 for control messages.
+ *
+ * The x bits are reserved for future extensions. All reserved bits MUST
+ * be set to 0 on outgoing messages and ignored on incoming messages.
+ *
+ * If the Sequence (S) bit is set to 1 the Ns and Nr fields are present.
+ * The S bit MUST be set to 1 for control messages.
+ *
+ * If the Offset (O) bit is 1, the Offset Size field is present. The O
+ * bit MUST be set to 0 for control messages.
+ *
+ * If the Priority (P) bit is 1, this data message should receive
+ * preferential treatment in its local queuing and transmission.
+ * The P bit MUST be set to 0 for control messages.
+ *
+ * Ver MUST be 2, indicating the version of the L2TP data message header.
+ *
+ * The Length field indicates the total length of the message in octets.
+ *
+ * Tunnel ID indicates the identifier for the control connection.
+ *
+ * Session ID indicates the identifier for a session within a tunnel.
+ *
+ * Ns indicates the sequence number for this data or control message.
+ *
+ * Nr indicates the sequence number expected in the next control message
+ * to be received.
+ *
+ * The Offset Size field, if present, specifies the number of octets
+ * past the L2TP header at which the payload data is expected to start.
+ * Actual data within the offset padding is undefined. If the offset
+ * field is present, the L2TP header ends after the last octet of the
+ * offset padding.
+ */
+
+#include <stdint.h>
+#include <rte_byteorder.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * L2TPv2 Common Header
+ */
+RTE_STD_C11
+struct rte_l2tpv2_common_hdr {
+	union {
+		rte_be16_t flags_version;
+		struct {
+#if RTE_BYTE_ORDER == RTE_LITTLE_ENDIAN
+			rte_be16_t t:1;		/**< message Type */
+			rte_be16_t l:1;		/**< length option bit*/
+			rte_be16_t res1:2;	/**< reserved */
+			rte_be16_t s:1;		/**< ns/nr option bit*/
+			rte_be16_t res2:1;	/**< reserved */
+			rte_be16_t o:1;		/**< offset option bit*/
+			rte_be16_t p:1;		/**< priority option bit*/
+			rte_be16_t res3:4;	/**< reserved */
+			rte_be16_t ver:4;	/**< protocol version */
+#elif RTE_BYTE_ORDER == RTE_BIG_ENDIAN
+			rte_be16_t ver:4;	/**< protocol version */
+			rte_be16_t res3:4;	/**< reserved */
+			rte_be16_t p:1;		/**< priority option bit*/
+			rte_be16_t o:1;		/**< offset option bit*/
+			rte_be16_t res2:1;	/**< reserved */
+			rte_be16_t s:1;		/**< ns/nr option bit*/
+			rte_be16_t res1:2;	/**< reserved */
+			rte_be16_t l:1;		/**< length option bit*/
+			rte_be16_t t:1;		/**< message Type */
+#endif
+		};
+	};
+};
+
+/*
+ * L2TPv2 message Header contains all options(length, ns, nr,
+ * offset size, offset padding).
+ */
+struct rte_l2tpv2_msg_with_all_options {
+	rte_be16_t length;		/**< length(16) */
+	rte_be16_t tunnel_id;		/**< tunnel id(16) */
+	rte_be16_t session_id;		/**< session id(16) */
+	rte_be16_t ns;			/**< Ns(16) */
+	rte_be16_t nr;			/**< Nr(16) */
+	rte_be16_t offset_size;		/**< offset size(16) */
+	uint8_t   *offset_padding;	/**< offset padding(variable length) */
+};
+
+/*
+ * L2TPv2 message Header contains all options except length(ns, nr,
+ * offset size, offset padding).
+ */
+struct rte_l2tpv2_msg_without_length {
+	rte_be16_t tunnel_id;		/**< tunnel id(16) */
+	rte_be16_t session_id;		/**< session id(16) */
+	rte_be16_t ns;			/**< Ns(16) */
+	rte_be16_t nr;			/**< Nr(16) */
+	rte_be16_t offset_size;		/**< offset size(16) */
+	uint8_t   *offset_padding;	/**< offset padding(variable length) */
+};
+
+/*
+ * L2TPv2 message Header contains all options except ns_nr(length,
+ * offset size, offset padding).
+ * Ns and Nr MUST be toghter.
+ */
+struct rte_l2tpv2_msg_without_ns_nr {
+	rte_be16_t length;		/**< length(16) */
+	rte_be16_t tunnel_id;		/**< tunnel id(16) */
+	rte_be16_t session_id;		/**< session id(16) */
+	rte_be16_t offset_size;		/**< offset size(16) */
+	uint8_t   *offset_padding;	/**< offset padding(variable length) */
+};
+
+/*
+ * L2TPv2 message Header contains all options except ns_nr(length, ns, nr).
+ * offset size and offset padding MUST be toghter.
+ */
+struct rte_l2tpv2_msg_without_offset {
+	rte_be16_t length;		/**< length(16) */
+	rte_be16_t tunnel_id;		/**< tunnel id(16) */
+	rte_be16_t session_id;		/**< session id(16) */
+	rte_be16_t ns;			/**< Ns(16) */
+	rte_be16_t nr;			/**< Nr(16) */
+};
+
+/*
+ * L2TPv2 message Header contains options offset size and offset padding.
+ */
+struct rte_l2tpv2_msg_with_offset {
+	rte_be16_t tunnel_id;		/**< tunnel id(16) */
+	rte_be16_t session_id;		/**< session id(16) */
+	rte_be16_t offset_size;		/**< offset size(16) */
+	uint8_t   *offset_padding;	/**< offset padding(variable length) */
+};
+
+/*
+ * L2TPv2 message Header contains options ns and nr.
+ */
+struct rte_l2tpv2_msg_with_ns_nr {
+	rte_be16_t tunnel_id;		/**< tunnel id(16) */
+	rte_be16_t session_id;		/**< session id(16) */
+	rte_be16_t ns;			/**< Ns(16) */
+	rte_be16_t nr;			/**< Nr(16) */
+};
+
+/*
+ * L2TPv2 message Header contains option length.
+ */
+struct rte_l2tpv2_msg_with_length {
+	rte_be16_t length;		/**< length(16) */
+	rte_be16_t tunnel_id;		/**< tunnel id(16) */
+	rte_be16_t session_id;		/**< session id(16) */
+};
+
+/*
+ * L2TPv2 message Header without all options.
+ */
+struct rte_l2tpv2_msg_without_all_options {
+	rte_be16_t tunnel_id;		/**< tunnel id(16) */
+	rte_be16_t session_id;		/**< session id(16) */
+};
+
+/**
+ * L2TPv2 Combined Message Header Format: Common Header + Options
+ */
+RTE_STD_C11
+struct rte_l2tpv2_combined_msg_hdr {
+	struct rte_l2tpv2_common_hdr common;
+	union {
+		struct rte_l2tpv2_msg_with_all_options type0;
+		struct rte_l2tpv2_msg_without_length type1;
+		struct rte_l2tpv2_msg_without_ns_nr type2;
+		struct rte_l2tpv2_msg_without_offset type3;
+		struct rte_l2tpv2_msg_with_offset type4;
+		struct rte_l2tpv2_msg_with_ns_nr type5;
+		struct rte_l2tpv2_msg_with_length type6;
+		struct rte_l2tpv2_msg_without_all_options type7;
+	};
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RTE_L2TPV2_H_ */
-- 
2.25.1


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

* Re: [dpdk-dev] [PATCH v2 3/3] ethdev: support PPPoL2TPv2oUDP RSS Hash
  2021-10-12 10:25   ` [dpdk-dev] [PATCH v2 3/3] ethdev: " Jie Wang
@ 2021-10-12 15:28     ` Ori Kam
  0 siblings, 0 replies; 71+ messages in thread
From: Ori Kam @ 2021-10-12 15:28 UTC (permalink / raw)
  To: Jie Wang, dev
  Cc: ferruh.yigit, NBU-Contact-Thomas Monjalon, andrew.rybchenko,
	xiaoyun.li, stevex.yang, jingjing.wu, beilei.xing, wenjun1.wu


Hi Jie,

The first comment you are missing the maintainer (me)

Second shouldn't this be the first patch of the series?

Third this patch is about matching on new protocols why there is RSS hash in the title?


> -----Original Message-----
> From: dev <dev-bounces@dpdk.org> On Behalf Of Jie Wang
> Sent: Tuesday, October 12, 2021 1:25 PM
> To: dev@dpdk.org
> Subject: [dpdk-dev] [PATCH v2 3/3] ethdev: support PPPoL2TPv2oUDP RSS Hash
> 
> Added flow pattern items and header formats of L2TPv2 and PPP to support PPP over L2TPv2 over UDP
> protocol RSS Hash.
> 
> Signed-off-by: Wenjun Wu <wenjun1.wu@intel.com>
> Signed-off-by: Jie Wang <jie1x.wang@intel.com>
> ---
>  doc/guides/prog_guide/rte_flow.rst     |  25 +++
>  doc/guides/rel_notes/release_21_11.rst |   5 +
>  lib/ethdev/rte_flow.c                  |   2 +
>  lib/ethdev/rte_flow.h                  |  65 ++++++++
>  lib/net/rte_l2tpv2.h                   | 214 +++++++++++++++++++++++++
>  5 files changed, 311 insertions(+)
>  create mode 100644 lib/net/rte_l2tpv2.h
> 
> diff --git a/doc/guides/prog_guide/rte_flow.rst b/doc/guides/prog_guide/rte_flow.rst
> index 2b42d5ec8c..e161fa8620 100644
> --- a/doc/guides/prog_guide/rte_flow.rst
> +++ b/doc/guides/prog_guide/rte_flow.rst
> @@ -1425,6 +1425,31 @@ Matches a conntrack state after conntrack action.
>  - ``flags``: conntrack packet state flags.
>  - Default ``mask`` matches all state bits.
> 
> +Item: ``L2TPV2``
> +^^^^^^^^^^^^^^^^^^^
> +
> +Matches a L2TPv2 header.
> +
> +- ``flags_version``: flags(12b), version(4b).
> +- ``length``: total length of the message.
> +- ``tunnel_id``: identifier for the control connection.
> +- ``session_id``: identifier for a session within a tunnel.
> +- ``ns``: sequence number for this date or control message.
> +- ``nr``: sequence number expected in the next control message to be received.
> +- ``offset_size``: offset of payload data.
> +- ``offset_padding``: offset padding, variable length.
> +- Default ``mask`` matches flags_version only.
> +
> +Item: ``PPP``
> +^^^^^^^^^^^^^^^^^^^
> +
> +Matches a PPP header.
> +
> +- ``addr``: ppp address.
> +- ``ctrl``: ppp control.
> +- ``proto_id``: ppp protocol identifier.
> +- Default ``mask`` matches addr, ctrl, proto_id.
> +
>  Actions
>  ~~~~~~~
> 
> diff --git a/doc/guides/rel_notes/release_21_11.rst b/doc/guides/rel_notes/release_21_11.rst
> index 93082723cf..af8e0733db 100644
> --- a/doc/guides/rel_notes/release_21_11.rst
> +++ b/doc/guides/rel_notes/release_21_11.rst
> @@ -67,6 +67,11 @@ New Features
>    Added macros ETH_RSS_IPV4_CHKSUM and ETH_RSS_L4_CHKSUM, now IPv4 and
>    TCP/UDP/SCTP header checksum field can be used as input set for RSS.
> 
> +* **Added L2TPV2 and PPP protocol support in rte_flow.**
> +
> +  Added flow pattern items and header formats of L2TPv2 and PPP to
> + support  PPP over L2TPv2 over UDP protocol RSS Hash.
> +
>  * **Updated Broadcom bnxt PMD.**
> 
>    * Added flow offload support for Thor.
> diff --git a/lib/ethdev/rte_flow.c b/lib/ethdev/rte_flow.c index 8cb7a069c8..307fbc3abe 100644
> --- a/lib/ethdev/rte_flow.c
> +++ b/lib/ethdev/rte_flow.c
> @@ -98,6 +98,8 @@ static const struct rte_flow_desc_data rte_flow_desc_item[] = {
>  	MK_FLOW_ITEM(PFCP, sizeof(struct rte_flow_item_pfcp)),
>  	MK_FLOW_ITEM(ECPRI, sizeof(struct rte_flow_item_ecpri)),
>  	MK_FLOW_ITEM(GENEVE_OPT, sizeof(struct rte_flow_item_geneve_opt)),
> +	MK_FLOW_ITEM(L2TPV2, sizeof(struct rte_flow_item_l2tpv2)),
> +	MK_FLOW_ITEM(PPP, sizeof(struct rte_flow_item_ppp)),

Why not in the end?

>  	MK_FLOW_ITEM(INTEGRITY, sizeof(struct rte_flow_item_integrity)),
>  	MK_FLOW_ITEM(CONNTRACK, sizeof(uint32_t)),  }; diff --git a/lib/ethdev/rte_flow.h
> b/lib/ethdev/rte_flow.h index 7b1ed7f110..a7a7bd983b 100644
> --- a/lib/ethdev/rte_flow.h
> +++ b/lib/ethdev/rte_flow.h
> @@ -35,6 +35,7 @@
>  #include <rte_mbuf_dyn.h>
>  #include <rte_meter.h>
>  #include <rte_gtp.h>
> +#include <rte_l2tpv2.h>
> 
>  #ifdef __cplusplus
>  extern "C" {
> @@ -574,6 +575,21 @@ enum rte_flow_item_type {
>  	 * @see struct rte_flow_item_conntrack.
>  	 */
>  	RTE_FLOW_ITEM_TYPE_CONNTRACK,
> +
> +	/**
> +	 * Matches L2TPV2 Header.
> +	 *
> +	 * See struct rte_flow_item_l2tpv2.
> +	 */
> +	RTE_FLOW_ITEM_TYPE_L2TPV2,
> +
> +	/**
> +	 * Matches PPP Header.
> +	 *
> +	 * See struct rte_flow_item_ppp.
> +	 */
> +	RTE_FLOW_ITEM_TYPE_PPP,
> +
>  };
> 
>  /**
> @@ -1799,6 +1815,55 @@ static const struct rte_flow_item_conntrack rte_flow_item_conntrack_mask
> = {  };  #endif
> 
> +/**
> + * @warning
> + * @b EXPERIMENTAL: this structure may change without prior notice
> + * RTE_FLOW_ITEM_TYPE_L2TPV2
> + *
> + * Matches L2TPv2 Header
> + */
> +struct rte_flow_item_l2tpv2 {
> +	struct rte_l2tpv2_combined_msg_hdr hdr; };
> +
> +/** Default mask for RTE_FLOW_ITEM_TYPE_L2TPV2. */ #ifndef __cplusplus
> +static const struct rte_flow_item_l2tpv2 rte_flow_item_l2tpv2_mask = {
> +	/*
> +	 * flags and version bit mask
> +	 * 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0
> +	 * T L x x S x O P x x x x V V V V
> +	 */
> +	.hdr = {
> +		.common = {
> +			.flags_version = 0xcb0f,
> +		},
> +	},
> +};
> +#endif
> +
> +/**
> + * @warning
> + * @b EXPERIMENTAL: this structure may change without prior notice
> + * RTE_FLOW_ITEM_TYPE_PPP
> + *
> + * Matches PPP Header
> + */
> +struct rte_flow_item_ppp {
> +	uint8_t addr; /**< ppp address(8) */
> +	uint8_t ctrl; /**< ppp control(8) */
> +	rte_be16_t proto_id; /**< ppp protocol id(16) */ };
> +
> +/** Default mask for RTE_FLOW_ITEM_TYPE_PPP. */ #ifndef __cplusplus
> +static const struct rte_flow_item_ppp rte_flow_item_ppp_mask = {
> +	.addr = 0xff,
> +	.ctrl = 0xff,
> +	.proto_id = 0xffff,
> +};
> +#endif
> +
>  /**
>   * Matching pattern item definition.
>   *
> diff --git a/lib/net/rte_l2tpv2.h b/lib/net/rte_l2tpv2.h new file mode 100644 index
> 0000000000..aea3c689be
> --- /dev/null
> +++ b/lib/net/rte_l2tpv2.h
> @@ -0,0 +1,214 @@
> +/* SPDX-License-Identifier: BSD-3-Clause
> + * Copyright 2021 Mellanox Technologies, Ltd  */
> +
> +#ifndef _RTE_L2TPV2_H_
> +#define _RTE_L2TPV2_H_
> +
> +/**
> + * @file
> + *
> + * L2TP header:
> + *  0                   1                   2                   3
> + *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
> + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
> + * |T|L|x|x|S|x|O|P|x|x|x|x|  Ver  |          Length (opt)         |
> + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
> + * |           Tunnel ID           |           Session ID          |
> + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
> + * |             Ns (opt)          |             Nr (opt)          |
> + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
> + * |      Offset Size (opt)        |    Offset pad... (opt)
> + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
> + *
> + * The Type (T) bit indicates the type of message. It is set to 0 for a
> +data
> + * message and 1 for a control message.
> + *
> + * If the Length (L) bit is 1, the Length field is present. This bit
> +MUST be
> + * set to 1 for control messages.
> + *
> + * The x bits are reserved for future extensions. All reserved bits
> +MUST
> + * be set to 0 on outgoing messages and ignored on incoming messages.
> + *
> + * If the Sequence (S) bit is set to 1 the Ns and Nr fields are present.
> + * The S bit MUST be set to 1 for control messages.
> + *
> + * If the Offset (O) bit is 1, the Offset Size field is present. The O
> + * bit MUST be set to 0 for control messages.
> + *
> + * If the Priority (P) bit is 1, this data message should receive
> + * preferential treatment in its local queuing and transmission.
> + * The P bit MUST be set to 0 for control messages.
> + *
> + * Ver MUST be 2, indicating the version of the L2TP data message header.
> + *
> + * The Length field indicates the total length of the message in octets.
> + *
> + * Tunnel ID indicates the identifier for the control connection.
> + *
> + * Session ID indicates the identifier for a session within a tunnel.
> + *
> + * Ns indicates the sequence number for this data or control message.
> + *
> + * Nr indicates the sequence number expected in the next control
> +message
> + * to be received.
> + *
> + * The Offset Size field, if present, specifies the number of octets
> + * past the L2TP header at which the payload data is expected to start.
> + * Actual data within the offset padding is undefined. If the offset
> + * field is present, the L2TP header ends after the last octet of the
> + * offset padding.
> + */
> +
> +#include <stdint.h>
> +#include <rte_byteorder.h>
> +
> +#ifdef __cplusplus
> +extern "C" {
> +#endif
> +
> +/**
> + * L2TPv2 Common Header
> + */
> +RTE_STD_C11
> +struct rte_l2tpv2_common_hdr {
> +	union {
> +		rte_be16_t flags_version;
> +		struct {
> +#if RTE_BYTE_ORDER == RTE_LITTLE_ENDIAN
> +			rte_be16_t t:1;		/**< message Type */
> +			rte_be16_t l:1;		/**< length option bit*/
> +			rte_be16_t res1:2;	/**< reserved */
> +			rte_be16_t s:1;		/**< ns/nr option bit*/
> +			rte_be16_t res2:1;	/**< reserved */
> +			rte_be16_t o:1;		/**< offset option bit*/
> +			rte_be16_t p:1;		/**< priority option bit*/
> +			rte_be16_t res3:4;	/**< reserved */
> +			rte_be16_t ver:4;	/**< protocol version */
> +#elif RTE_BYTE_ORDER == RTE_BIG_ENDIAN
> +			rte_be16_t ver:4;	/**< protocol version */
> +			rte_be16_t res3:4;	/**< reserved */
> +			rte_be16_t p:1;		/**< priority option bit*/
> +			rte_be16_t o:1;		/**< offset option bit*/
> +			rte_be16_t res2:1;	/**< reserved */
> +			rte_be16_t s:1;		/**< ns/nr option bit*/
> +			rte_be16_t res1:2;	/**< reserved */
> +			rte_be16_t l:1;		/**< length option bit*/
> +			rte_be16_t t:1;		/**< message Type */
> +#endif
> +		};
> +	};
> +};
> +
> +/*
> + * L2TPv2 message Header contains all options(length, ns, nr,
> + * offset size, offset padding).
> + */
> +struct rte_l2tpv2_msg_with_all_options {
> +	rte_be16_t length;		/**< length(16) */
> +	rte_be16_t tunnel_id;		/**< tunnel id(16) */
> +	rte_be16_t session_id;		/**< session id(16) */
> +	rte_be16_t ns;			/**< Ns(16) */
> +	rte_be16_t nr;			/**< Nr(16) */
> +	rte_be16_t offset_size;		/**< offset size(16) */
> +	uint8_t   *offset_padding;	/**< offset padding(variable length) */
> +};
> +
> +/*
> + * L2TPv2 message Header contains all options except length(ns, nr,
> + * offset size, offset padding).
> + */
> +struct rte_l2tpv2_msg_without_length {
> +	rte_be16_t tunnel_id;		/**< tunnel id(16) */
> +	rte_be16_t session_id;		/**< session id(16) */
> +	rte_be16_t ns;			/**< Ns(16) */
> +	rte_be16_t nr;			/**< Nr(16) */
> +	rte_be16_t offset_size;		/**< offset size(16) */
> +	uint8_t   *offset_padding;	/**< offset padding(variable length) */
> +};
> +
> +/*
> + * L2TPv2 message Header contains all options except ns_nr(length,
> + * offset size, offset padding).
> + * Ns and Nr MUST be toghter.
> + */
> +struct rte_l2tpv2_msg_without_ns_nr {
> +	rte_be16_t length;		/**< length(16) */
> +	rte_be16_t tunnel_id;		/**< tunnel id(16) */
> +	rte_be16_t session_id;		/**< session id(16) */
> +	rte_be16_t offset_size;		/**< offset size(16) */
> +	uint8_t   *offset_padding;	/**< offset padding(variable length) */
> +};
> +
> +/*
> + * L2TPv2 message Header contains all options except ns_nr(length, ns, nr).
> + * offset size and offset padding MUST be toghter.
> + */
> +struct rte_l2tpv2_msg_without_offset {
> +	rte_be16_t length;		/**< length(16) */
> +	rte_be16_t tunnel_id;		/**< tunnel id(16) */
> +	rte_be16_t session_id;		/**< session id(16) */
> +	rte_be16_t ns;			/**< Ns(16) */
> +	rte_be16_t nr;			/**< Nr(16) */
> +};
> +
> +/*
> + * L2TPv2 message Header contains options offset size and offset padding.
> + */
> +struct rte_l2tpv2_msg_with_offset {
> +	rte_be16_t tunnel_id;		/**< tunnel id(16) */
> +	rte_be16_t session_id;		/**< session id(16) */
> +	rte_be16_t offset_size;		/**< offset size(16) */
> +	uint8_t   *offset_padding;	/**< offset padding(variable length) */
> +};
> +
> +/*
> + * L2TPv2 message Header contains options ns and nr.
> + */
> +struct rte_l2tpv2_msg_with_ns_nr {
> +	rte_be16_t tunnel_id;		/**< tunnel id(16) */
> +	rte_be16_t session_id;		/**< session id(16) */
> +	rte_be16_t ns;			/**< Ns(16) */
> +	rte_be16_t nr;			/**< Nr(16) */
> +};
> +
> +/*
> + * L2TPv2 message Header contains option length.
> + */
> +struct rte_l2tpv2_msg_with_length {
> +	rte_be16_t length;		/**< length(16) */
> +	rte_be16_t tunnel_id;		/**< tunnel id(16) */
> +	rte_be16_t session_id;		/**< session id(16) */
> +};
> +
> +/*
> + * L2TPv2 message Header without all options.
> + */
> +struct rte_l2tpv2_msg_without_all_options {
> +	rte_be16_t tunnel_id;		/**< tunnel id(16) */
> +	rte_be16_t session_id;		/**< session id(16) */
> +};
> +
> +/**
> + * L2TPv2 Combined Message Header Format: Common Header + Options  */
> +RTE_STD_C11
> +struct rte_l2tpv2_combined_msg_hdr {
> +	struct rte_l2tpv2_common_hdr common;
> +	union {
> +		struct rte_l2tpv2_msg_with_all_options type0;
> +		struct rte_l2tpv2_msg_without_length type1;
> +		struct rte_l2tpv2_msg_without_ns_nr type2;
> +		struct rte_l2tpv2_msg_without_offset type3;
> +		struct rte_l2tpv2_msg_with_offset type4;
> +		struct rte_l2tpv2_msg_with_ns_nr type5;
> +		struct rte_l2tpv2_msg_with_length type6;
> +		struct rte_l2tpv2_msg_without_all_options type7;
> +	};
> +};
> +
> +#ifdef __cplusplus
> +}
> +#endif
> +
> +#endif /* _RTE_L2TPV2_H_ */
> --
> 2.25.1

Best,
Ori

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

* Re: [dpdk-dev] [PATCH v2 2/3] app/testpmd: support PPPoL2TPv2oUDP RSS Hash
  2021-10-12 10:25   ` [dpdk-dev] [PATCH v2 2/3] app/testpmd: " Jie Wang
@ 2021-10-12 15:31     ` Ori Kam
  2021-10-13  8:15       ` Wang, Jie1X
  0 siblings, 1 reply; 71+ messages in thread
From: Ori Kam @ 2021-10-12 15:31 UTC (permalink / raw)
  To: Jie Wang, dev
  Cc: ferruh.yigit, NBU-Contact-Thomas Monjalon, andrew.rybchenko,
	xiaoyun.li, stevex.yang, jingjing.wu, beilei.xing, wenjun1.wu

Hi Jie,

> -----Original Message-----
> From: dev <dev-bounces@dpdk.org> On Behalf Of Jie Wang
> Sent: Tuesday, October 12, 2021 1:25 PM
> Subject: [dpdk-dev] [PATCH v2 2/3] app/testpmd: support PPPoL2TPv2oUDP RSS Hash
> 
> Add support for test-pmd to parse protocol pattern L2TPv2 and PPP.
> 
> Signed-off-by: Wenjun Wu <wenjun1.wu@intel.com>
> Signed-off-by: Jie Wang <jie1x.wang@intel.com>
> ---
>  app/test-pmd/cmdline_flow.c | 34 ++++++++++++++++++++++++++++++++++
>  1 file changed, 34 insertions(+)
> 
> diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c index
> bb22294dd3..3c9bcabd97 100644
> --- a/app/test-pmd/cmdline_flow.c
> +++ b/app/test-pmd/cmdline_flow.c
> @@ -299,6 +299,8 @@ enum index {
>  	ITEM_GENEVE_OPT_TYPE,
>  	ITEM_GENEVE_OPT_LENGTH,
>  	ITEM_GENEVE_OPT_DATA,
> +	ITEM_PPP,
> +	ITEM_L2TPV2,
>  	ITEM_INTEGRITY,
>  	ITEM_INTEGRITY_LEVEL,
>  	ITEM_INTEGRITY_VALUE,
> @@ -997,6 +999,8 @@ static const enum index next_item[] = {
>  	ITEM_AH,
>  	ITEM_PFCP,
>  	ITEM_ECPRI,
> +	ITEM_PPP,
> +	ITEM_L2TPV2,

Why in the middle?

>  	ITEM_GENEVE_OPT,
>  	ITEM_INTEGRITY,
>  	ITEM_CONNTRACK,
> @@ -1368,6 +1372,16 @@ static const enum index item_integrity_lv[] = {
>  	ZERO,
>  };
> 
> +static const enum index item_ppp[] = {
> +	ITEM_NEXT,
> +	ZERO,
> +};
> +
> +static const enum index item_l2tpv2[] = {
> +	ITEM_NEXT,
> +	ZERO,
> +};
> +
>  static const enum index next_action[] = {
>  	ACTION_END,
>  	ACTION_VOID,
> @@ -3579,6 +3593,20 @@ static const struct token token_list[] = {
>  				(sizeof(struct rte_flow_item_geneve_opt),
>  				ITEM_GENEVE_OPT_DATA_SIZE)),
>  	},
> +	[ITEM_PPP] = {
> +		.name = "ppp",
> +		.help = "match ppp header",
> +		.priv = PRIV_ITEM(PPP, sizeof(struct rte_flow_item_ppp)),
> +		.next = NEXT(item_ppp),
> +		.call = parse_vc,
> +	},
> +	[ITEM_L2TPV2] = {
> +		.name = "l2tpv2",
> +		.help = "match l2tpv2 header",
> +		.priv = PRIV_ITEM(L2TPV2, sizeof(struct rte_flow_item_l2tpv2)),
> +		.next = NEXT(item_l2tpv2),
> +		.call = parse_vc,
> +	},
>  	[ITEM_INTEGRITY] = {
>  		.name = "integrity",
>  		.help = "match packet integrity",
> @@ -8343,6 +8371,12 @@ flow_item_default_mask(const struct rte_flow_item *item)
>  	case RTE_FLOW_ITEM_TYPE_PFCP:
>  		mask = &rte_flow_item_pfcp_mask;
>  		break;
> +	case RTE_FLOW_ITEM_TYPE_L2TPV2:
> +		mask = &rte_flow_item_l2tpv2_mask;
> +		break;
> +	case RTE_FLOW_ITEM_TYPE_PPP:
> +		mask = &rte_flow_item_ppp_mask;
> +		break;
>  	default:
>  		break;
>  	}
> --
> 2.25.1

Maybe I'm missing something but I don't see that you added the ability to match on any
of the header fields value.
You also didn't update the code of encap (from my understanding this is a tunnel header)

Best,
Ori


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

* Re: [dpdk-dev] [PATCH v2 2/3] app/testpmd: support PPPoL2TPv2oUDP RSS Hash
  2021-10-12 15:31     ` Ori Kam
@ 2021-10-13  8:15       ` Wang, Jie1X
  2021-10-13  9:15         ` Ori Kam
  0 siblings, 1 reply; 71+ messages in thread
From: Wang, Jie1X @ 2021-10-13  8:15 UTC (permalink / raw)
  To: Ori Kam, dev
  Cc: Yigit, Ferruh, NBU-Contact-Thomas Monjalon, andrew.rybchenko, Li,
	Xiaoyun, Yang,  SteveX, Wu, Jingjing, Xing, Beilei, Wu, Wenjun1



> -----Original Message-----
> From: Ori Kam <orika@nvidia.com>
> Sent: Tuesday, October 12, 2021 11:32 PM
> To: Wang, Jie1X <jie1x.wang@intel.com>; dev@dpdk.org
> Cc: Yigit, Ferruh <ferruh.yigit@intel.com>; NBU-Contact-Thomas Monjalon
> <thomas@monjalon.net>; andrew.rybchenko@oktetlabs.ru; Li, Xiaoyun
> <xiaoyun.li@intel.com>; Yang, SteveX <stevex.yang@intel.com>; Wu, Jingjing
> <jingjing.wu@intel.com>; Xing, Beilei <beilei.xing@intel.com>; Wu, Wenjun1
> <wenjun1.wu@intel.com>
> Subject: RE: [dpdk-dev] [PATCH v2 2/3] app/testpmd: support PPPoL2TPv2oUDP
> RSS Hash
> 
> Hi Jie,
> 
> > -----Original Message-----
> > From: dev <dev-bounces@dpdk.org> On Behalf Of Jie Wang
> > Sent: Tuesday, October 12, 2021 1:25 PM
> > Subject: [dpdk-dev] [PATCH v2 2/3] app/testpmd: support PPPoL2TPv2oUDP
> > RSS Hash
> >
> > Add support for test-pmd to parse protocol pattern L2TPv2 and PPP.
> >
> > Signed-off-by: Wenjun Wu <wenjun1.wu@intel.com>
> > Signed-off-by: Jie Wang <jie1x.wang@intel.com>
> > ---
> >  app/test-pmd/cmdline_flow.c | 34 ++++++++++++++++++++++++++++++++++
> >  1 file changed, 34 insertions(+)
> >
> > diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
> > index
> > bb22294dd3..3c9bcabd97 100644
> > --- a/app/test-pmd/cmdline_flow.c
> > +++ b/app/test-pmd/cmdline_flow.c
> > @@ -299,6 +299,8 @@ enum index {
> >  	ITEM_GENEVE_OPT_TYPE,
> >  	ITEM_GENEVE_OPT_LENGTH,
> >  	ITEM_GENEVE_OPT_DATA,
> > +	ITEM_PPP,
> > +	ITEM_L2TPV2,
> >  	ITEM_INTEGRITY,
> >  	ITEM_INTEGRITY_LEVEL,
> >  	ITEM_INTEGRITY_VALUE,
> > @@ -997,6 +999,8 @@ static const enum index next_item[] = {
> >  	ITEM_AH,
> >  	ITEM_PFCP,
> >  	ITEM_ECPRI,
> > +	ITEM_PPP,
> > +	ITEM_L2TPV2,
> 
> Why in the middle?
> 

Ok, I will update it.

> >  	ITEM_GENEVE_OPT,
> >  	ITEM_INTEGRITY,
> >  	ITEM_CONNTRACK,
> > @@ -1368,6 +1372,16 @@ static const enum index item_integrity_lv[] = {
> >  	ZERO,
> >  };
> >
> > +static const enum index item_ppp[] = {
> > +	ITEM_NEXT,
> > +	ZERO,
> > +};
> > +
> > +static const enum index item_l2tpv2[] = {
> > +	ITEM_NEXT,
> > +	ZERO,
> > +};
> > +
> >  static const enum index next_action[] = {
> >  	ACTION_END,
> >  	ACTION_VOID,
> > @@ -3579,6 +3593,20 @@ static const struct token token_list[] = {
> >  				(sizeof(struct rte_flow_item_geneve_opt),
> >  				ITEM_GENEVE_OPT_DATA_SIZE)),
> >  	},
> > +	[ITEM_PPP] = {
> > +		.name = "ppp",
> > +		.help = "match ppp header",
> > +		.priv = PRIV_ITEM(PPP, sizeof(struct rte_flow_item_ppp)),
> > +		.next = NEXT(item_ppp),
> > +		.call = parse_vc,
> > +	},
> > +	[ITEM_L2TPV2] = {
> > +		.name = "l2tpv2",
> > +		.help = "match l2tpv2 header",
> > +		.priv = PRIV_ITEM(L2TPV2, sizeof(struct rte_flow_item_l2tpv2)),
> > +		.next = NEXT(item_l2tpv2),
> > +		.call = parse_vc,
> > +	},
> >  	[ITEM_INTEGRITY] = {
> >  		.name = "integrity",
> >  		.help = "match packet integrity",
> > @@ -8343,6 +8371,12 @@ flow_item_default_mask(const struct
> rte_flow_item *item)
> >  	case RTE_FLOW_ITEM_TYPE_PFCP:
> >  		mask = &rte_flow_item_pfcp_mask;
> >  		break;
> > +	case RTE_FLOW_ITEM_TYPE_L2TPV2:
> > +		mask = &rte_flow_item_l2tpv2_mask;
> > +		break;
> > +	case RTE_FLOW_ITEM_TYPE_PPP:
> > +		mask = &rte_flow_item_ppp_mask;
> > +		break;
> >  	default:
> >  		break;
> >  	}
> > --
> > 2.25.1
> 
> Maybe I'm missing something but I don't see that you added the ability to match
> on any of the header fields value.
> You also didn't update the code of encap (from my understanding this is a tunnel
> header)
> 
> Best,
> Ori

Hi Ori,

This feature is only support for iavf enable PPPoL2TPv2oUDP rss. So it doesn't need to add the ability to match on any of the header fields value and the code of encap.

I'm not sure if it is necessary to add these.

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

* Re: [dpdk-dev] [PATCH v2 2/3] app/testpmd: support PPPoL2TPv2oUDP RSS Hash
  2021-10-13  8:15       ` Wang, Jie1X
@ 2021-10-13  9:15         ` Ori Kam
  2021-10-13  9:54           ` Wang, Jie1X
  0 siblings, 1 reply; 71+ messages in thread
From: Ori Kam @ 2021-10-13  9:15 UTC (permalink / raw)
  To: Wang, Jie1X, dev
  Cc: Yigit, Ferruh, NBU-Contact-Thomas Monjalon, andrew.rybchenko, Li,
	Xiaoyun, Yang,  SteveX, Wu, Jingjing, Xing, Beilei, Wu, Wenjun1

Hi Wang,

> -----Original Message-----
> From: Wang, Jie1X <jie1x.wang@intel.com>
> Sent: Wednesday, October 13, 2021 11:16 AM
>
> Subject: RE: [dpdk-dev] [PATCH v2 2/3] app/testpmd: support PPPoL2TPv2oUDP RSS Hash
> 
> 
> 
> > -----Original Message-----
> > From: Ori Kam <orika@nvidia.com>
> > Sent: Tuesday, October 12, 2021 11:32 PM
> > To: Wang, Jie1X <jie1x.wang@intel.com>; dev@dpdk.org
> > Cc: Yigit, Ferruh <ferruh.yigit@intel.com>; NBU-Contact-Thomas
> > Monjalon <thomas@monjalon.net>; andrew.rybchenko@oktetlabs.ru; Li,
> > Xiaoyun <xiaoyun.li@intel.com>; Yang, SteveX <stevex.yang@intel.com>;
> > Wu, Jingjing <jingjing.wu@intel.com>; Xing, Beilei
> > <beilei.xing@intel.com>; Wu, Wenjun1 <wenjun1.wu@intel.com>
> > Subject: RE: [dpdk-dev] [PATCH v2 2/3] app/testpmd: support
> > PPPoL2TPv2oUDP RSS Hash
> >
> > Hi Jie,
> >
> > > -----Original Message-----
> > > From: dev <dev-bounces@dpdk.org> On Behalf Of Jie Wang
> > > Sent: Tuesday, October 12, 2021 1:25 PM
> > > Subject: [dpdk-dev] [PATCH v2 2/3] app/testpmd: support
> > > PPPoL2TPv2oUDP RSS Hash
> > >
> > > Add support for test-pmd to parse protocol pattern L2TPv2 and PPP.
> > >
> > > Signed-off-by: Wenjun Wu <wenjun1.wu@intel.com>
> > > Signed-off-by: Jie Wang <jie1x.wang@intel.com>
> > > ---
> > >  app/test-pmd/cmdline_flow.c | 34 ++++++++++++++++++++++++++++++++++
> > >  1 file changed, 34 insertions(+)
> > >
> > > diff --git a/app/test-pmd/cmdline_flow.c
> > > b/app/test-pmd/cmdline_flow.c index
> > > bb22294dd3..3c9bcabd97 100644
> > > --- a/app/test-pmd/cmdline_flow.c
> > > +++ b/app/test-pmd/cmdline_flow.c
> > > @@ -299,6 +299,8 @@ enum index {
> > >  	ITEM_GENEVE_OPT_TYPE,
> > >  	ITEM_GENEVE_OPT_LENGTH,
> > >  	ITEM_GENEVE_OPT_DATA,
> > > +	ITEM_PPP,
> > > +	ITEM_L2TPV2,
> > >  	ITEM_INTEGRITY,
> > >  	ITEM_INTEGRITY_LEVEL,
> > >  	ITEM_INTEGRITY_VALUE,
> > > @@ -997,6 +999,8 @@ static const enum index next_item[] = {
> > >  	ITEM_AH,
> > >  	ITEM_PFCP,
> > >  	ITEM_ECPRI,
> > > +	ITEM_PPP,
> > > +	ITEM_L2TPV2,
> >
> > Why in the middle?
> >
> 
> Ok, I will update it.
> 
> > >  	ITEM_GENEVE_OPT,
> > >  	ITEM_INTEGRITY,
> > >  	ITEM_CONNTRACK,
> > > @@ -1368,6 +1372,16 @@ static const enum index item_integrity_lv[] = {
> > >  	ZERO,
> > >  };
> > >
> > > +static const enum index item_ppp[] = {
> > > +	ITEM_NEXT,
> > > +	ZERO,
> > > +};
> > > +
> > > +static const enum index item_l2tpv2[] = {
> > > +	ITEM_NEXT,
> > > +	ZERO,
> > > +};
> > > +
> > >  static const enum index next_action[] = {
> > >  	ACTION_END,
> > >  	ACTION_VOID,
> > > @@ -3579,6 +3593,20 @@ static const struct token token_list[] = {
> > >  				(sizeof(struct rte_flow_item_geneve_opt),
> > >  				ITEM_GENEVE_OPT_DATA_SIZE)),
> > >  	},
> > > +	[ITEM_PPP] = {
> > > +		.name = "ppp",
> > > +		.help = "match ppp header",
> > > +		.priv = PRIV_ITEM(PPP, sizeof(struct rte_flow_item_ppp)),
> > > +		.next = NEXT(item_ppp),
> > > +		.call = parse_vc,
> > > +	},
> > > +	[ITEM_L2TPV2] = {
> > > +		.name = "l2tpv2",
> > > +		.help = "match l2tpv2 header",
> > > +		.priv = PRIV_ITEM(L2TPV2, sizeof(struct rte_flow_item_l2tpv2)),
> > > +		.next = NEXT(item_l2tpv2),
> > > +		.call = parse_vc,
> > > +	},
> > >  	[ITEM_INTEGRITY] = {
> > >  		.name = "integrity",
> > >  		.help = "match packet integrity", @@ -8343,6 +8371,12 @@
> > > flow_item_default_mask(const struct
> > rte_flow_item *item)
> > >  	case RTE_FLOW_ITEM_TYPE_PFCP:
> > >  		mask = &rte_flow_item_pfcp_mask;
> > >  		break;
> > > +	case RTE_FLOW_ITEM_TYPE_L2TPV2:
> > > +		mask = &rte_flow_item_l2tpv2_mask;
> > > +		break;
> > > +	case RTE_FLOW_ITEM_TYPE_PPP:
> > > +		mask = &rte_flow_item_ppp_mask;
> > > +		break;
> > >  	default:
> > >  		break;
> > >  	}
> > > --
> > > 2.25.1
> >
> > Maybe I'm missing something but I don't see that you added the ability
> > to match on any of the header fields value.
> > You also didn't update the code of encap (from my understanding this
> > is a tunnel
> > header)
> >
> > Best,
> > Ori
> 
> Hi Ori,
> 
> This feature is only support for iavf enable PPPoL2TPv2oUDP rss. So it doesn't need to add the ability
> to match on any of the header fields value and the code of encap.
> 
> I'm not sure if it is necessary to add these.

You added a lot of fields in the rte_flow and you don't give any way to test them. 
also Iike I said in previous patch what is the relation between matching items to RSS?
You didn't add it to the RSS possible support.

Best,
Ori

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

* Re: [dpdk-dev] [PATCH v2 2/3] app/testpmd: support PPPoL2TPv2oUDP RSS Hash
  2021-10-13  9:15         ` Ori Kam
@ 2021-10-13  9:54           ` Wang, Jie1X
  2021-10-13 10:19             ` Ori Kam
  0 siblings, 1 reply; 71+ messages in thread
From: Wang, Jie1X @ 2021-10-13  9:54 UTC (permalink / raw)
  To: Ori Kam, dev
  Cc: Yigit, Ferruh, NBU-Contact-Thomas Monjalon, andrew.rybchenko, Li,
	Xiaoyun, Yang,  SteveX, Wu, Jingjing, Xing, Beilei, Wu, Wenjun1



> -----Original Message-----
> From: Ori Kam <orika@nvidia.com>
> Sent: Wednesday, October 13, 2021 5:15 PM
> To: Wang, Jie1X <jie1x.wang@intel.com>; dev@dpdk.org
> Cc: Yigit, Ferruh <ferruh.yigit@intel.com>; NBU-Contact-Thomas Monjalon
> <thomas@monjalon.net>; andrew.rybchenko@oktetlabs.ru; Li, Xiaoyun
> <xiaoyun.li@intel.com>; Yang, SteveX <stevex.yang@intel.com>; Wu, Jingjing
> <jingjing.wu@intel.com>; Xing, Beilei <beilei.xing@intel.com>; Wu, Wenjun1
> <wenjun1.wu@intel.com>
> Subject: RE: [dpdk-dev] [PATCH v2 2/3] app/testpmd: support PPPoL2TPv2oUDP
> RSS Hash
> 
> Hi Wang,
> 
> > -----Original Message-----
> > From: Wang, Jie1X <jie1x.wang@intel.com>
> > Sent: Wednesday, October 13, 2021 11:16 AM
> >
> > Subject: RE: [dpdk-dev] [PATCH v2 2/3] app/testpmd: support
> > PPPoL2TPv2oUDP RSS Hash
> >
> >
> >
> > > -----Original Message-----
> > > From: Ori Kam <orika@nvidia.com>
> > > Sent: Tuesday, October 12, 2021 11:32 PM
> > > To: Wang, Jie1X <jie1x.wang@intel.com>; dev@dpdk.org
> > > Cc: Yigit, Ferruh <ferruh.yigit@intel.com>; NBU-Contact-Thomas
> > > Monjalon <thomas@monjalon.net>; andrew.rybchenko@oktetlabs.ru; Li,
> > > Xiaoyun <xiaoyun.li@intel.com>; Yang, SteveX
> > > <stevex.yang@intel.com>; Wu, Jingjing <jingjing.wu@intel.com>; Xing,
> > > Beilei <beilei.xing@intel.com>; Wu, Wenjun1 <wenjun1.wu@intel.com>
> > > Subject: RE: [dpdk-dev] [PATCH v2 2/3] app/testpmd: support
> > > PPPoL2TPv2oUDP RSS Hash
> > >
> > > Hi Jie,
> > >
> > > > -----Original Message-----
> > > > From: dev <dev-bounces@dpdk.org> On Behalf Of Jie Wang
> > > > Sent: Tuesday, October 12, 2021 1:25 PM
> > > > Subject: [dpdk-dev] [PATCH v2 2/3] app/testpmd: support
> > > > PPPoL2TPv2oUDP RSS Hash
> > > >
> > > > Add support for test-pmd to parse protocol pattern L2TPv2 and PPP.
> > > >
> > > > Signed-off-by: Wenjun Wu <wenjun1.wu@intel.com>
> > > > Signed-off-by: Jie Wang <jie1x.wang@intel.com>
> > > > ---
> > > >  app/test-pmd/cmdline_flow.c | 34
> > > > ++++++++++++++++++++++++++++++++++
> > > >  1 file changed, 34 insertions(+)
> > > >
> > > > diff --git a/app/test-pmd/cmdline_flow.c
> > > > b/app/test-pmd/cmdline_flow.c index
> > > > bb22294dd3..3c9bcabd97 100644
> > > > --- a/app/test-pmd/cmdline_flow.c
> > > > +++ b/app/test-pmd/cmdline_flow.c
> > > > @@ -299,6 +299,8 @@ enum index {
> > > >  	ITEM_GENEVE_OPT_TYPE,
> > > >  	ITEM_GENEVE_OPT_LENGTH,
> > > >  	ITEM_GENEVE_OPT_DATA,
> > > > +	ITEM_PPP,
> > > > +	ITEM_L2TPV2,
> > > >  	ITEM_INTEGRITY,
> > > >  	ITEM_INTEGRITY_LEVEL,
> > > >  	ITEM_INTEGRITY_VALUE,
> > > > @@ -997,6 +999,8 @@ static const enum index next_item[] = {
> > > >  	ITEM_AH,
> > > >  	ITEM_PFCP,
> > > >  	ITEM_ECPRI,
> > > > +	ITEM_PPP,
> > > > +	ITEM_L2TPV2,
> > >
> > > Why in the middle?
> > >
> >
> > Ok, I will update it.
> >
> > > >  	ITEM_GENEVE_OPT,
> > > >  	ITEM_INTEGRITY,
> > > >  	ITEM_CONNTRACK,
> > > > @@ -1368,6 +1372,16 @@ static const enum index item_integrity_lv[] = {
> > > >  	ZERO,
> > > >  };
> > > >
> > > > +static const enum index item_ppp[] = {
> > > > +	ITEM_NEXT,
> > > > +	ZERO,
> > > > +};
> > > > +
> > > > +static const enum index item_l2tpv2[] = {
> > > > +	ITEM_NEXT,
> > > > +	ZERO,
> > > > +};
> > > > +
> > > >  static const enum index next_action[] = {
> > > >  	ACTION_END,
> > > >  	ACTION_VOID,
> > > > @@ -3579,6 +3593,20 @@ static const struct token token_list[] = {
> > > >  				(sizeof(struct rte_flow_item_geneve_opt),
> > > >  				ITEM_GENEVE_OPT_DATA_SIZE)),
> > > >  	},
> > > > +	[ITEM_PPP] = {
> > > > +		.name = "ppp",
> > > > +		.help = "match ppp header",
> > > > +		.priv = PRIV_ITEM(PPP, sizeof(struct rte_flow_item_ppp)),
> > > > +		.next = NEXT(item_ppp),
> > > > +		.call = parse_vc,
> > > > +	},
> > > > +	[ITEM_L2TPV2] = {
> > > > +		.name = "l2tpv2",
> > > > +		.help = "match l2tpv2 header",
> > > > +		.priv = PRIV_ITEM(L2TPV2, sizeof(struct rte_flow_item_l2tpv2)),
> > > > +		.next = NEXT(item_l2tpv2),
> > > > +		.call = parse_vc,
> > > > +	},
> > > >  	[ITEM_INTEGRITY] = {
> > > >  		.name = "integrity",
> > > >  		.help = "match packet integrity", @@ -8343,6 +8371,12 @@
> > > > flow_item_default_mask(const struct
> > > rte_flow_item *item)
> > > >  	case RTE_FLOW_ITEM_TYPE_PFCP:
> > > >  		mask = &rte_flow_item_pfcp_mask;
> > > >  		break;
> > > > +	case RTE_FLOW_ITEM_TYPE_L2TPV2:
> > > > +		mask = &rte_flow_item_l2tpv2_mask;
> > > > +		break;
> > > > +	case RTE_FLOW_ITEM_TYPE_PPP:
> > > > +		mask = &rte_flow_item_ppp_mask;
> > > > +		break;
> > > >  	default:
> > > >  		break;
> > > >  	}
> > > > --
> > > > 2.25.1
> > >
> > > Maybe I'm missing something but I don't see that you added the
> > > ability to match on any of the header fields value.
> > > You also didn't update the code of encap (from my understanding this
> > > is a tunnel
> > > header)
> > >
> > > Best,
> > > Ori
> >
> > Hi Ori,
> >
> > This feature is only support for iavf enable PPPoL2TPv2oUDP rss. So it
> > doesn't need to add the ability to match on any of the header fields value and
> the code of encap.
> >
> > I'm not sure if it is necessary to add these.
> 
> You added a lot of fields in the rte_flow and you don't give any way to test them.
> also Iike I said in previous patch what is the relation between matching items to
> RSS?
> You didn't add it to the RSS possible support.
> 
> Best,
> Ori

The feature apply a RSS rule on L2TP data packet (include PPP over L2TP) with inner IP / port as input set.
It doesn't need match any L2TP field.

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

* Re: [dpdk-dev] [PATCH v2 2/3] app/testpmd: support PPPoL2TPv2oUDP RSS Hash
  2021-10-13  9:54           ` Wang, Jie1X
@ 2021-10-13 10:19             ` Ori Kam
  0 siblings, 0 replies; 71+ messages in thread
From: Ori Kam @ 2021-10-13 10:19 UTC (permalink / raw)
  To: Wang, Jie1X, dev
  Cc: Yigit, Ferruh, NBU-Contact-Thomas Monjalon, andrew.rybchenko, Li,
	Xiaoyun, Yang,  SteveX, Wu, Jingjing, Xing, Beilei, Wu, Wenjun1



> -----Original Message-----
> From: Wang, Jie1X <jie1x.wang@intel.com>
> Sent: Wednesday, October 13, 2021 12:54 PM
> Subject: RE: [dpdk-dev] [PATCH v2 2/3] app/testpmd: support PPPoL2TPv2oUDP RSS Hash
> 
> 
> 
> > -----Original Message-----
> > From: Ori Kam <orika@nvidia.com>
> > Sent: Wednesday, October 13, 2021 5:15 PM
> > To: Wang, Jie1X <jie1x.wang@intel.com>; dev@dpdk.org
> > Cc: Yigit, Ferruh <ferruh.yigit@intel.com>; NBU-Contact-Thomas
> > Monjalon <thomas@monjalon.net>; andrew.rybchenko@oktetlabs.ru; Li,
> > Xiaoyun <xiaoyun.li@intel.com>; Yang, SteveX <stevex.yang@intel.com>;
> > Wu, Jingjing <jingjing.wu@intel.com>; Xing, Beilei
> > <beilei.xing@intel.com>; Wu, Wenjun1 <wenjun1.wu@intel.com>
> > Subject: RE: [dpdk-dev] [PATCH v2 2/3] app/testpmd: support
> > PPPoL2TPv2oUDP RSS Hash
> >
> > Hi Wang,
> >
> > > -----Original Message-----
> > > From: Wang, Jie1X <jie1x.wang@intel.com>
> > > Sent: Wednesday, October 13, 2021 11:16 AM
> > >
> > > Subject: RE: [dpdk-dev] [PATCH v2 2/3] app/testpmd: support
> > > PPPoL2TPv2oUDP RSS Hash
> > >
> > >
> > >
> > > > -----Original Message-----
> > > > From: Ori Kam <orika@nvidia.com>
> > > > Sent: Tuesday, October 12, 2021 11:32 PM
> > > > To: Wang, Jie1X <jie1x.wang@intel.com>; dev@dpdk.org
> > > > Cc: Yigit, Ferruh <ferruh.yigit@intel.com>; NBU-Contact-Thomas
> > > > Monjalon <thomas@monjalon.net>; andrew.rybchenko@oktetlabs.ru; Li,
> > > > Xiaoyun <xiaoyun.li@intel.com>; Yang, SteveX
> > > > <stevex.yang@intel.com>; Wu, Jingjing <jingjing.wu@intel.com>;
> > > > Xing, Beilei <beilei.xing@intel.com>; Wu, Wenjun1
> > > > <wenjun1.wu@intel.com>
> > > > Subject: RE: [dpdk-dev] [PATCH v2 2/3] app/testpmd: support
> > > > PPPoL2TPv2oUDP RSS Hash
> > > >
> > > > Hi Jie,
> > > >
> > > > > -----Original Message-----
> > > > > From: dev <dev-bounces@dpdk.org> On Behalf Of Jie Wang
> > > > > Sent: Tuesday, October 12, 2021 1:25 PM
> > > > > Subject: [dpdk-dev] [PATCH v2 2/3] app/testpmd: support
> > > > > PPPoL2TPv2oUDP RSS Hash
> > > > >
> > > > > Add support for test-pmd to parse protocol pattern L2TPv2 and PPP.
> > > > >
> > > > > Signed-off-by: Wenjun Wu <wenjun1.wu@intel.com>
> > > > > Signed-off-by: Jie Wang <jie1x.wang@intel.com>
> > > > > ---
> > > > >  app/test-pmd/cmdline_flow.c | 34
> > > > > ++++++++++++++++++++++++++++++++++
> > > > >  1 file changed, 34 insertions(+)
> > > > >
> > > > > diff --git a/app/test-pmd/cmdline_flow.c
> > > > > b/app/test-pmd/cmdline_flow.c index
> > > > > bb22294dd3..3c9bcabd97 100644
> > > > > --- a/app/test-pmd/cmdline_flow.c
> > > > > +++ b/app/test-pmd/cmdline_flow.c
> > > > > @@ -299,6 +299,8 @@ enum index {
> > > > >  	ITEM_GENEVE_OPT_TYPE,
> > > > >  	ITEM_GENEVE_OPT_LENGTH,
> > > > >  	ITEM_GENEVE_OPT_DATA,
> > > > > +	ITEM_PPP,
> > > > > +	ITEM_L2TPV2,
> > > > >  	ITEM_INTEGRITY,
> > > > >  	ITEM_INTEGRITY_LEVEL,
> > > > >  	ITEM_INTEGRITY_VALUE,
> > > > > @@ -997,6 +999,8 @@ static const enum index next_item[] = {
> > > > >  	ITEM_AH,
> > > > >  	ITEM_PFCP,
> > > > >  	ITEM_ECPRI,
> > > > > +	ITEM_PPP,
> > > > > +	ITEM_L2TPV2,
> > > >
> > > > Why in the middle?
> > > >
> > >
> > > Ok, I will update it.
> > >
> > > > >  	ITEM_GENEVE_OPT,
> > > > >  	ITEM_INTEGRITY,
> > > > >  	ITEM_CONNTRACK,
> > > > > @@ -1368,6 +1372,16 @@ static const enum index item_integrity_lv[] = {
> > > > >  	ZERO,
> > > > >  };
> > > > >
> > > > > +static const enum index item_ppp[] = {
> > > > > +	ITEM_NEXT,
> > > > > +	ZERO,
> > > > > +};
> > > > > +
> > > > > +static const enum index item_l2tpv2[] = {
> > > > > +	ITEM_NEXT,
> > > > > +	ZERO,
> > > > > +};
> > > > > +
> > > > >  static const enum index next_action[] = {
> > > > >  	ACTION_END,
> > > > >  	ACTION_VOID,
> > > > > @@ -3579,6 +3593,20 @@ static const struct token token_list[] = {
> > > > >  				(sizeof(struct rte_flow_item_geneve_opt),
> > > > >  				ITEM_GENEVE_OPT_DATA_SIZE)),
> > > > >  	},
> > > > > +	[ITEM_PPP] = {
> > > > > +		.name = "ppp",
> > > > > +		.help = "match ppp header",
> > > > > +		.priv = PRIV_ITEM(PPP, sizeof(struct rte_flow_item_ppp)),
> > > > > +		.next = NEXT(item_ppp),
> > > > > +		.call = parse_vc,
> > > > > +	},
> > > > > +	[ITEM_L2TPV2] = {
> > > > > +		.name = "l2tpv2",
> > > > > +		.help = "match l2tpv2 header",
> > > > > +		.priv = PRIV_ITEM(L2TPV2, sizeof(struct rte_flow_item_l2tpv2)),
> > > > > +		.next = NEXT(item_l2tpv2),
> > > > > +		.call = parse_vc,
> > > > > +	},
> > > > >  	[ITEM_INTEGRITY] = {
> > > > >  		.name = "integrity",
> > > > >  		.help = "match packet integrity", @@ -8343,6 +8371,12 @@
> > > > > flow_item_default_mask(const struct
> > > > rte_flow_item *item)
> > > > >  	case RTE_FLOW_ITEM_TYPE_PFCP:
> > > > >  		mask = &rte_flow_item_pfcp_mask;
> > > > >  		break;
> > > > > +	case RTE_FLOW_ITEM_TYPE_L2TPV2:
> > > > > +		mask = &rte_flow_item_l2tpv2_mask;
> > > > > +		break;
> > > > > +	case RTE_FLOW_ITEM_TYPE_PPP:
> > > > > +		mask = &rte_flow_item_ppp_mask;
> > > > > +		break;
> > > > >  	default:
> > > > >  		break;
> > > > >  	}
> > > > > --
> > > > > 2.25.1
> > > >
> > > > Maybe I'm missing something but I don't see that you added the
> > > > ability to match on any of the header fields value.
> > > > You also didn't update the code of encap (from my understanding
> > > > this is a tunnel
> > > > header)
> > > >
> > > > Best,
> > > > Ori
> > >
> > > Hi Ori,
> > >
> > > This feature is only support for iavf enable PPPoL2TPv2oUDP rss. So
> > > it doesn't need to add the ability to match on any of the header
> > > fields value and
> > the code of encap.
> > >
> > > I'm not sure if it is necessary to add these.
> >
> > You added a lot of fields in the rte_flow and you don't give any way to test them.
> > also Iike I said in previous patch what is the relation between
> > matching items to RSS?
> > You didn't add it to the RSS possible support.
> >
> > Best,
> > Ori
> 
> The feature apply a RSS rule on L2TP data packet (include PPP over L2TP) with inner IP / port as input
> set.
> It doesn't need match any L2TP field.

Just to be clear when you say RSS on mean RSS on ipv4+udp for example not on the ppp header itself right?
If so then the title should just state that you are adding new items (also for other patches)
since I can use this item to jump to other group or count or any other action. This patch dosesn't have anything to do with hash.

I understand that from your point of view you don't need to match on any field, but you added such fields and no one
can test it and no PMD support this so this feature is not valid.

Best,
Ori

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

* [dpdk-dev] [PATCH v3 0/3] support PPPoL2TPv2oUDP RSS Hash
  2021-10-12 10:25 ` [dpdk-dev] [PATCH v2 0/3] support PPPoL2TPv2oUDP " Jie Wang
                     ` (2 preceding siblings ...)
  2021-10-12 10:25   ` [dpdk-dev] [PATCH v2 3/3] ethdev: " Jie Wang
@ 2021-10-15  9:58   ` Jie Wang
  2021-10-15  9:58     ` [dpdk-dev] [PATCH v3 1/3] ethdev: support PPP and L2TPV2 procotol Jie Wang
                       ` (3 more replies)
  3 siblings, 4 replies; 71+ messages in thread
From: Jie Wang @ 2021-10-15  9:58 UTC (permalink / raw)
  To: dev
  Cc: orika, ferruh.yigit, thomas, andrew.rybchenko, xiaoyun.li,
	stevex.yang, jingjing.wu, beilei.xing, wenjun1.wu, Jie Wang

Support IAVF PPPoL2TPv2oUDP RSS Hash. Required to distribute packets
based on inner IP src+dest address and TCP/UDP src+dest port.

---
v3:
 * add testpmd match ppp and l2tpv2 protocol header fields value.
 * add the code of l2tpv2_encap.
 * update the title of ethdev patch and adjust the position of
   the added code.

v2:
 * update the rte_flow.rst and release notes.
 * update l2tpv2 header format.

Jie Wang (3):
  ethdev: support PPP and L2TPV2 procotol
  net/iavf: support PPPoL2TPv2oUDP RSS Hash
  app/testpmd: support L2TPV2 and PPP protocol pattern

 app/test-pmd/cmdline.c                 | 244 +++++++++++++++
 app/test-pmd/cmdline_flow.c            | 396 +++++++++++++++++++++++++
 app/test-pmd/testpmd.h                 |  22 ++
 doc/guides/prog_guide/rte_flow.rst     |  25 ++
 doc/guides/rel_notes/release_21_11.rst |   5 +
 drivers/net/iavf/iavf_generic_flow.c   | 131 ++++++++
 drivers/net/iavf/iavf_generic_flow.h   |  15 +
 drivers/net/iavf/iavf_hash.c           | 108 ++++++-
 lib/ethdev/rte_flow.c                  |   2 +
 lib/ethdev/rte_flow.h                  | 117 ++++++++
 lib/net/rte_l2tpv2.h                   | 214 +++++++++++++
 11 files changed, 1277 insertions(+), 2 deletions(-)
 create mode 100644 lib/net/rte_l2tpv2.h

-- 
2.25.1


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

* [dpdk-dev] [PATCH v3 1/3] ethdev: support PPP and L2TPV2 procotol
  2021-10-15  9:58   ` [dpdk-dev] [PATCH v3 0/3] " Jie Wang
@ 2021-10-15  9:58     ` Jie Wang
  2021-10-15 11:10       ` Ferruh Yigit
  2021-10-17  8:19       ` Ori Kam
  2021-10-15  9:58     ` [dpdk-dev] [PATCH v3 2/3] net/iavf: support PPPoL2TPv2oUDP RSS Hash Jie Wang
                       ` (2 subsequent siblings)
  3 siblings, 2 replies; 71+ messages in thread
From: Jie Wang @ 2021-10-15  9:58 UTC (permalink / raw)
  To: dev
  Cc: orika, ferruh.yigit, thomas, andrew.rybchenko, xiaoyun.li,
	stevex.yang, jingjing.wu, beilei.xing, wenjun1.wu, Jie Wang

Added flow pattern items and header formats of L2TPv2 and PPP to
support PPP over L2TPv2 over UDP protocol RSS Hash.

Signed-off-by: Wenjun Wu <wenjun1.wu@intel.com>
Signed-off-by: Jie Wang <jie1x.wang@intel.com>
---
 doc/guides/prog_guide/rte_flow.rst     |  25 +++
 doc/guides/rel_notes/release_21_11.rst |   5 +
 lib/ethdev/rte_flow.c                  |   2 +
 lib/ethdev/rte_flow.h                  | 117 ++++++++++++++
 lib/net/rte_l2tpv2.h                   | 214 +++++++++++++++++++++++++
 5 files changed, 363 insertions(+)
 create mode 100644 lib/net/rte_l2tpv2.h

diff --git a/doc/guides/prog_guide/rte_flow.rst b/doc/guides/prog_guide/rte_flow.rst
index 3cb014c1fa..59fe7e79b5 100644
--- a/doc/guides/prog_guide/rte_flow.rst
+++ b/doc/guides/prog_guide/rte_flow.rst
@@ -1425,6 +1425,31 @@ Matches a conntrack state after conntrack action.
 - ``flags``: conntrack packet state flags.
 - Default ``mask`` matches all state bits.
 
+Item: ``L2TPV2``
+^^^^^^^^^^^^^^^^^^^
+
+Matches a L2TPv2 header.
+
+- ``flags_version``: flags(12b), version(4b).
+- ``length``: total length of the message.
+- ``tunnel_id``: identifier for the control connection.
+- ``session_id``: identifier for a session within a tunnel.
+- ``ns``: sequence number for this date or control message.
+- ``nr``: sequence number expected in the next control message to be received.
+- ``offset_size``: offset of payload data.
+- ``offset_padding``: offset padding, variable length.
+- Default ``mask`` matches flags_version only.
+
+Item: ``PPP``
+^^^^^^^^^^^^^^^^^^^
+
+Matches a PPP header.
+
+- ``addr``: ppp address.
+- ``ctrl``: ppp control.
+- ``proto_id``: ppp protocol identifier.
+- Default ``mask`` matches addr, ctrl, proto_id.
+
 Actions
 ~~~~~~~
 
diff --git a/doc/guides/rel_notes/release_21_11.rst b/doc/guides/rel_notes/release_21_11.rst
index d5c762df62..503f6dd828 100644
--- a/doc/guides/rel_notes/release_21_11.rst
+++ b/doc/guides/rel_notes/release_21_11.rst
@@ -81,6 +81,11 @@ New Features
   * Default VLAN strip behavior was changed. VLAN tag won't be stripped
     unless ``DEV_RX_OFFLOAD_VLAN_STRIP`` offload is enabled.
 
+* **Added L2TPV2 and PPP protocol support in rte_flow.**
+
+  Added flow pattern items and header formats of L2TPv2 and PPP to support
+  PPP over L2TPv2 over UDP protocol RSS Hash.
+
 * **Updated AF_XDP PMD.**
 
   * Disabled secondary process support.
diff --git a/lib/ethdev/rte_flow.c b/lib/ethdev/rte_flow.c
index 8cb7a069c8..1ec739a031 100644
--- a/lib/ethdev/rte_flow.c
+++ b/lib/ethdev/rte_flow.c
@@ -100,6 +100,8 @@ static const struct rte_flow_desc_data rte_flow_desc_item[] = {
 	MK_FLOW_ITEM(GENEVE_OPT, sizeof(struct rte_flow_item_geneve_opt)),
 	MK_FLOW_ITEM(INTEGRITY, sizeof(struct rte_flow_item_integrity)),
 	MK_FLOW_ITEM(CONNTRACK, sizeof(uint32_t)),
+	MK_FLOW_ITEM(L2TPV2, sizeof(struct rte_flow_item_l2tpv2)),
+	MK_FLOW_ITEM(PPP, sizeof(struct rte_flow_item_ppp)),
 };
 
 /** Generate flow_action[] entry. */
diff --git a/lib/ethdev/rte_flow.h b/lib/ethdev/rte_flow.h
index 5f87851f8c..f8fcf9c1f8 100644
--- a/lib/ethdev/rte_flow.h
+++ b/lib/ethdev/rte_flow.h
@@ -35,6 +35,7 @@
 #include <rte_mbuf_dyn.h>
 #include <rte_meter.h>
 #include <rte_gtp.h>
+#include <rte_l2tpv2.h>
 
 #ifdef __cplusplus
 extern "C" {
@@ -574,6 +575,21 @@ enum rte_flow_item_type {
 	 * @see struct rte_flow_item_conntrack.
 	 */
 	RTE_FLOW_ITEM_TYPE_CONNTRACK,
+
+	/**
+	 * Matches L2TPV2 Header.
+	 *
+	 * See struct rte_flow_item_l2tpv2.
+	 */
+	RTE_FLOW_ITEM_TYPE_L2TPV2,
+
+	/**
+	 * Matches PPP Header.
+	 *
+	 * See struct rte_flow_item_ppp.
+	 */
+	RTE_FLOW_ITEM_TYPE_PPP,
+
 };
 
 /**
@@ -1799,6 +1815,55 @@ static const struct rte_flow_item_conntrack rte_flow_item_conntrack_mask = {
 };
 #endif
 
+/**
+ * @warning
+ * @b EXPERIMENTAL: this structure may change without prior notice
+ * RTE_FLOW_ITEM_TYPE_L2TPV2
+ *
+ * Matches L2TPv2 Header
+ */
+struct rte_flow_item_l2tpv2 {
+	struct rte_l2tpv2_combined_msg_hdr hdr;
+};
+
+/** Default mask for RTE_FLOW_ITEM_TYPE_L2TPV2. */
+#ifndef __cplusplus
+static const struct rte_flow_item_l2tpv2 rte_flow_item_l2tpv2_mask = {
+	/*
+	 * flags and version bit mask
+	 * 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0
+	 * T L x x S x O P x x x x V V V V
+	 */
+	.hdr = {
+		.common = {
+			.flags_version = 0xcb0f,
+		},
+	},
+};
+#endif
+
+/**
+ * @warning
+ * @b EXPERIMENTAL: this structure may change without prior notice
+ * RTE_FLOW_ITEM_TYPE_PPP
+ *
+ * Matches PPP Header
+ */
+struct rte_flow_item_ppp {
+	uint8_t addr; /**< ppp address(8) */
+	uint8_t ctrl; /**< ppp control(8) */
+	rte_be16_t proto_id; /**< ppp protocol id(16) */
+};
+
+/** Default mask for RTE_FLOW_ITEM_TYPE_PPP. */
+#ifndef __cplusplus
+static const struct rte_flow_item_ppp rte_flow_item_ppp_mask = {
+	.addr = 0xff,
+	.ctrl = 0xff,
+	.proto_id = 0xffff,
+};
+#endif
+
 /**
  * Matching pattern item definition.
  *
@@ -2417,6 +2482,23 @@ enum rte_flow_action_type {
 	 * See struct rte_flow_action_meter_color.
 	 */
 	RTE_FLOW_ACTION_TYPE_METER_COLOR,
+
+	/**
+	 * Encapsulate flow in L2TPV2 tunnel defined in the
+	 * rte_flow_action_l2tpv2_encap action structure.
+	 *
+	 * See struct rte_flow_action_l2tpv2_encap.
+	 */
+	RTE_FLOW_ACTION_TYPE_L2TPV2_ENCAP,
+
+	/**
+	 * Decapsulate outer most L2TPV2 tunnel from matched flow.
+	 *
+	 * If flow pattern does not define a valid L2TPV2 tunnel (as specified
+	 * by RFC2661) then the PMD should return a RTE_FLOW_ERROR_TYPE_ACTION
+	 * error.
+	 */
+	RTE_FLOW_ACTION_TYPE_L2TPV2_DECAP,
 };
 
 /**
@@ -3162,6 +3244,41 @@ struct rte_flow_action_meter_color {
 	enum rte_color color; /**< Packet color. */
 };
 
+/**
+ * @warning
+ * @b EXPERIMENTAL: this structure may change without prior notice
+ *
+ * RTE_FLOW_ACTION_TYPE_L2TPV2_ENCAP
+ *
+ * L2TPV2 tunnel end-point encapsulation data definition
+ *
+ * The tunnel definition is provided through the flow item pattern  the
+ * provided pattern must conform with RFC7637. The flow definition must be
+ * provided in order from the RTE_FLOW_ITEM_TYPE_ETH definition up the end item
+ * which is specified by RTE_FLOW_ITEM_TYPE_END.
+ *
+ * The mask field allows user to specify which fields in the flow item
+ * definitions can be ignored and which have valid data and can be used
+ * verbatim.
+ *
+ * Note: the last field is not used in the definition of a tunnel and can be
+ * ignored.
+ *
+ * Valid flow definition for RTE_FLOW_ACTION_TYPE_L2TPV2_ENCAP include:
+ *
+ * - ETH / IPV4 / UDP / L2TPV2 / END
+ * - ETH / IPV6 / UDP / L2TPV2 / END
+ * - ETH / VLAN / IPV4 / UDP / L2TPV2 / END
+ *
+ */
+struct rte_flow_action_l2tpv2_encap {
+	/**
+	 * Encapsulating l2tpv2 tunnel definition
+	 * (terminated by the END pattern item).
+	 */
+	struct rte_flow_item *definition;
+};
+
 /**
  * Field IDs for MODIFY_FIELD action.
  */
diff --git a/lib/net/rte_l2tpv2.h b/lib/net/rte_l2tpv2.h
new file mode 100644
index 0000000000..aea3c689be
--- /dev/null
+++ b/lib/net/rte_l2tpv2.h
@@ -0,0 +1,214 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright 2021 Mellanox Technologies, Ltd
+ */
+
+#ifndef _RTE_L2TPV2_H_
+#define _RTE_L2TPV2_H_
+
+/**
+ * @file
+ *
+ * L2TP header:
+ *  0                   1                   2                   3
+ *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |T|L|x|x|S|x|O|P|x|x|x|x|  Ver  |          Length (opt)         |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |           Tunnel ID           |           Session ID          |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |             Ns (opt)          |             Nr (opt)          |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |      Offset Size (opt)        |    Offset pad... (opt)
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *
+ * The Type (T) bit indicates the type of message. It is set to 0 for a data
+ * message and 1 for a control message.
+ *
+ * If the Length (L) bit is 1, the Length field is present. This bit MUST be
+ * set to 1 for control messages.
+ *
+ * The x bits are reserved for future extensions. All reserved bits MUST
+ * be set to 0 on outgoing messages and ignored on incoming messages.
+ *
+ * If the Sequence (S) bit is set to 1 the Ns and Nr fields are present.
+ * The S bit MUST be set to 1 for control messages.
+ *
+ * If the Offset (O) bit is 1, the Offset Size field is present. The O
+ * bit MUST be set to 0 for control messages.
+ *
+ * If the Priority (P) bit is 1, this data message should receive
+ * preferential treatment in its local queuing and transmission.
+ * The P bit MUST be set to 0 for control messages.
+ *
+ * Ver MUST be 2, indicating the version of the L2TP data message header.
+ *
+ * The Length field indicates the total length of the message in octets.
+ *
+ * Tunnel ID indicates the identifier for the control connection.
+ *
+ * Session ID indicates the identifier for a session within a tunnel.
+ *
+ * Ns indicates the sequence number for this data or control message.
+ *
+ * Nr indicates the sequence number expected in the next control message
+ * to be received.
+ *
+ * The Offset Size field, if present, specifies the number of octets
+ * past the L2TP header at which the payload data is expected to start.
+ * Actual data within the offset padding is undefined. If the offset
+ * field is present, the L2TP header ends after the last octet of the
+ * offset padding.
+ */
+
+#include <stdint.h>
+#include <rte_byteorder.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * L2TPv2 Common Header
+ */
+RTE_STD_C11
+struct rte_l2tpv2_common_hdr {
+	union {
+		rte_be16_t flags_version;
+		struct {
+#if RTE_BYTE_ORDER == RTE_LITTLE_ENDIAN
+			rte_be16_t t:1;		/**< message Type */
+			rte_be16_t l:1;		/**< length option bit*/
+			rte_be16_t res1:2;	/**< reserved */
+			rte_be16_t s:1;		/**< ns/nr option bit*/
+			rte_be16_t res2:1;	/**< reserved */
+			rte_be16_t o:1;		/**< offset option bit*/
+			rte_be16_t p:1;		/**< priority option bit*/
+			rte_be16_t res3:4;	/**< reserved */
+			rte_be16_t ver:4;	/**< protocol version */
+#elif RTE_BYTE_ORDER == RTE_BIG_ENDIAN
+			rte_be16_t ver:4;	/**< protocol version */
+			rte_be16_t res3:4;	/**< reserved */
+			rte_be16_t p:1;		/**< priority option bit*/
+			rte_be16_t o:1;		/**< offset option bit*/
+			rte_be16_t res2:1;	/**< reserved */
+			rte_be16_t s:1;		/**< ns/nr option bit*/
+			rte_be16_t res1:2;	/**< reserved */
+			rte_be16_t l:1;		/**< length option bit*/
+			rte_be16_t t:1;		/**< message Type */
+#endif
+		};
+	};
+};
+
+/*
+ * L2TPv2 message Header contains all options(length, ns, nr,
+ * offset size, offset padding).
+ */
+struct rte_l2tpv2_msg_with_all_options {
+	rte_be16_t length;		/**< length(16) */
+	rte_be16_t tunnel_id;		/**< tunnel id(16) */
+	rte_be16_t session_id;		/**< session id(16) */
+	rte_be16_t ns;			/**< Ns(16) */
+	rte_be16_t nr;			/**< Nr(16) */
+	rte_be16_t offset_size;		/**< offset size(16) */
+	uint8_t   *offset_padding;	/**< offset padding(variable length) */
+};
+
+/*
+ * L2TPv2 message Header contains all options except length(ns, nr,
+ * offset size, offset padding).
+ */
+struct rte_l2tpv2_msg_without_length {
+	rte_be16_t tunnel_id;		/**< tunnel id(16) */
+	rte_be16_t session_id;		/**< session id(16) */
+	rte_be16_t ns;			/**< Ns(16) */
+	rte_be16_t nr;			/**< Nr(16) */
+	rte_be16_t offset_size;		/**< offset size(16) */
+	uint8_t   *offset_padding;	/**< offset padding(variable length) */
+};
+
+/*
+ * L2TPv2 message Header contains all options except ns_nr(length,
+ * offset size, offset padding).
+ * Ns and Nr MUST be toghter.
+ */
+struct rte_l2tpv2_msg_without_ns_nr {
+	rte_be16_t length;		/**< length(16) */
+	rte_be16_t tunnel_id;		/**< tunnel id(16) */
+	rte_be16_t session_id;		/**< session id(16) */
+	rte_be16_t offset_size;		/**< offset size(16) */
+	uint8_t   *offset_padding;	/**< offset padding(variable length) */
+};
+
+/*
+ * L2TPv2 message Header contains all options except ns_nr(length, ns, nr).
+ * offset size and offset padding MUST be toghter.
+ */
+struct rte_l2tpv2_msg_without_offset {
+	rte_be16_t length;		/**< length(16) */
+	rte_be16_t tunnel_id;		/**< tunnel id(16) */
+	rte_be16_t session_id;		/**< session id(16) */
+	rte_be16_t ns;			/**< Ns(16) */
+	rte_be16_t nr;			/**< Nr(16) */
+};
+
+/*
+ * L2TPv2 message Header contains options offset size and offset padding.
+ */
+struct rte_l2tpv2_msg_with_offset {
+	rte_be16_t tunnel_id;		/**< tunnel id(16) */
+	rte_be16_t session_id;		/**< session id(16) */
+	rte_be16_t offset_size;		/**< offset size(16) */
+	uint8_t   *offset_padding;	/**< offset padding(variable length) */
+};
+
+/*
+ * L2TPv2 message Header contains options ns and nr.
+ */
+struct rte_l2tpv2_msg_with_ns_nr {
+	rte_be16_t tunnel_id;		/**< tunnel id(16) */
+	rte_be16_t session_id;		/**< session id(16) */
+	rte_be16_t ns;			/**< Ns(16) */
+	rte_be16_t nr;			/**< Nr(16) */
+};
+
+/*
+ * L2TPv2 message Header contains option length.
+ */
+struct rte_l2tpv2_msg_with_length {
+	rte_be16_t length;		/**< length(16) */
+	rte_be16_t tunnel_id;		/**< tunnel id(16) */
+	rte_be16_t session_id;		/**< session id(16) */
+};
+
+/*
+ * L2TPv2 message Header without all options.
+ */
+struct rte_l2tpv2_msg_without_all_options {
+	rte_be16_t tunnel_id;		/**< tunnel id(16) */
+	rte_be16_t session_id;		/**< session id(16) */
+};
+
+/**
+ * L2TPv2 Combined Message Header Format: Common Header + Options
+ */
+RTE_STD_C11
+struct rte_l2tpv2_combined_msg_hdr {
+	struct rte_l2tpv2_common_hdr common;
+	union {
+		struct rte_l2tpv2_msg_with_all_options type0;
+		struct rte_l2tpv2_msg_without_length type1;
+		struct rte_l2tpv2_msg_without_ns_nr type2;
+		struct rte_l2tpv2_msg_without_offset type3;
+		struct rte_l2tpv2_msg_with_offset type4;
+		struct rte_l2tpv2_msg_with_ns_nr type5;
+		struct rte_l2tpv2_msg_with_length type6;
+		struct rte_l2tpv2_msg_without_all_options type7;
+	};
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RTE_L2TPV2_H_ */
-- 
2.25.1


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

* [dpdk-dev] [PATCH v3 2/3] net/iavf: support PPPoL2TPv2oUDP RSS Hash
  2021-10-15  9:58   ` [dpdk-dev] [PATCH v3 0/3] " Jie Wang
  2021-10-15  9:58     ` [dpdk-dev] [PATCH v3 1/3] ethdev: support PPP and L2TPV2 procotol Jie Wang
@ 2021-10-15  9:58     ` Jie Wang
  2021-10-15  9:58     ` [dpdk-dev] [PATCH v3 3/3] app/testpmd: support L2TPV2 and PPP protocol pattern Jie Wang
  2021-10-18  9:33     ` [dpdk-dev] [PATCH v4 0/3] support PPPoL2TPv2oUDP RSS Hash Jie Wang
  3 siblings, 0 replies; 71+ messages in thread
From: Jie Wang @ 2021-10-15  9:58 UTC (permalink / raw)
  To: dev
  Cc: orika, ferruh.yigit, thomas, andrew.rybchenko, xiaoyun.li,
	stevex.yang, jingjing.wu, beilei.xing, wenjun1.wu, Jie Wang

Add support for PPP over L2TPv2 over UDP protocol RSS Hash based
on inner IP src/dst address and TCP/UDP src/dst port.

Patterns are listed below:
eth/ipv4(6)/udp/l2tpv2/ppp/ipv4(6)
eth/ipv4(6)/udp/l2tpv2/ppp/ipv4(6)/udp
eth/ipv4(6)/udp/l2tpv2/ppp/ipv4(6)/tcp

Signed-off-by: Wenjun Wu <wenjun1.wu@intel.com>
Signed-off-by: Jie Wang <jie1x.wang@intel.com>
---
 drivers/net/iavf/iavf_generic_flow.c | 131 +++++++++++++++++++++++++++
 drivers/net/iavf/iavf_generic_flow.h |  15 +++
 drivers/net/iavf/iavf_hash.c         | 108 +++++++++++++++++++++-
 3 files changed, 252 insertions(+), 2 deletions(-)

diff --git a/drivers/net/iavf/iavf_generic_flow.c b/drivers/net/iavf/iavf_generic_flow.c
index b86d99e57d..364904fa02 100644
--- a/drivers/net/iavf/iavf_generic_flow.c
+++ b/drivers/net/iavf/iavf_generic_flow.c
@@ -1611,6 +1611,137 @@ enum rte_flow_item_type iavf_pattern_eth_ipv6_gre_ipv6_udp[] = {
 	RTE_FLOW_ITEM_TYPE_END,
 };
 
+/* PPPoL2TPv2oUDP */
+enum rte_flow_item_type iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv4[] = {
+	RTE_FLOW_ITEM_TYPE_ETH,
+	RTE_FLOW_ITEM_TYPE_IPV4,
+	RTE_FLOW_ITEM_TYPE_UDP,
+	RTE_FLOW_ITEM_TYPE_L2TPV2,
+	RTE_FLOW_ITEM_TYPE_PPP,
+	RTE_FLOW_ITEM_TYPE_IPV4,
+	RTE_FLOW_ITEM_TYPE_END,
+};
+
+enum rte_flow_item_type iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv6[] = {
+	RTE_FLOW_ITEM_TYPE_ETH,
+	RTE_FLOW_ITEM_TYPE_IPV4,
+	RTE_FLOW_ITEM_TYPE_UDP,
+	RTE_FLOW_ITEM_TYPE_L2TPV2,
+	RTE_FLOW_ITEM_TYPE_PPP,
+	RTE_FLOW_ITEM_TYPE_IPV6,
+	RTE_FLOW_ITEM_TYPE_END,
+};
+
+enum rte_flow_item_type iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv4_udp[] = {
+	RTE_FLOW_ITEM_TYPE_ETH,
+	RTE_FLOW_ITEM_TYPE_IPV4,
+	RTE_FLOW_ITEM_TYPE_UDP,
+	RTE_FLOW_ITEM_TYPE_L2TPV2,
+	RTE_FLOW_ITEM_TYPE_PPP,
+	RTE_FLOW_ITEM_TYPE_IPV4,
+	RTE_FLOW_ITEM_TYPE_UDP,
+	RTE_FLOW_ITEM_TYPE_END,
+};
+
+enum rte_flow_item_type iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv4_tcp[] = {
+	RTE_FLOW_ITEM_TYPE_ETH,
+	RTE_FLOW_ITEM_TYPE_IPV4,
+	RTE_FLOW_ITEM_TYPE_UDP,
+	RTE_FLOW_ITEM_TYPE_L2TPV2,
+	RTE_FLOW_ITEM_TYPE_PPP,
+	RTE_FLOW_ITEM_TYPE_IPV4,
+	RTE_FLOW_ITEM_TYPE_TCP,
+	RTE_FLOW_ITEM_TYPE_END,
+};
+
+enum rte_flow_item_type iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv6_udp[] = {
+	RTE_FLOW_ITEM_TYPE_ETH,
+	RTE_FLOW_ITEM_TYPE_IPV4,
+	RTE_FLOW_ITEM_TYPE_UDP,
+	RTE_FLOW_ITEM_TYPE_L2TPV2,
+	RTE_FLOW_ITEM_TYPE_PPP,
+	RTE_FLOW_ITEM_TYPE_IPV6,
+	RTE_FLOW_ITEM_TYPE_UDP,
+	RTE_FLOW_ITEM_TYPE_END,
+};
+
+enum rte_flow_item_type iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv6_tcp[] = {
+	RTE_FLOW_ITEM_TYPE_ETH,
+	RTE_FLOW_ITEM_TYPE_IPV4,
+	RTE_FLOW_ITEM_TYPE_UDP,
+	RTE_FLOW_ITEM_TYPE_L2TPV2,
+	RTE_FLOW_ITEM_TYPE_PPP,
+	RTE_FLOW_ITEM_TYPE_IPV6,
+	RTE_FLOW_ITEM_TYPE_TCP,
+	RTE_FLOW_ITEM_TYPE_END,
+};
+
+enum rte_flow_item_type iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv4[] = {
+	RTE_FLOW_ITEM_TYPE_ETH,
+	RTE_FLOW_ITEM_TYPE_IPV6,
+	RTE_FLOW_ITEM_TYPE_UDP,
+	RTE_FLOW_ITEM_TYPE_L2TPV2,
+	RTE_FLOW_ITEM_TYPE_PPP,
+	RTE_FLOW_ITEM_TYPE_IPV4,
+	RTE_FLOW_ITEM_TYPE_END,
+};
+
+enum rte_flow_item_type iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv6[] = {
+	RTE_FLOW_ITEM_TYPE_ETH,
+	RTE_FLOW_ITEM_TYPE_IPV6,
+	RTE_FLOW_ITEM_TYPE_UDP,
+	RTE_FLOW_ITEM_TYPE_L2TPV2,
+	RTE_FLOW_ITEM_TYPE_PPP,
+	RTE_FLOW_ITEM_TYPE_IPV6,
+	RTE_FLOW_ITEM_TYPE_END,
+};
+
+enum rte_flow_item_type iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv4_udp[] = {
+	RTE_FLOW_ITEM_TYPE_ETH,
+	RTE_FLOW_ITEM_TYPE_IPV6,
+	RTE_FLOW_ITEM_TYPE_UDP,
+	RTE_FLOW_ITEM_TYPE_L2TPV2,
+	RTE_FLOW_ITEM_TYPE_PPP,
+	RTE_FLOW_ITEM_TYPE_IPV4,
+	RTE_FLOW_ITEM_TYPE_UDP,
+	RTE_FLOW_ITEM_TYPE_END,
+};
+
+enum rte_flow_item_type iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv4_tcp[] = {
+	RTE_FLOW_ITEM_TYPE_ETH,
+	RTE_FLOW_ITEM_TYPE_IPV6,
+	RTE_FLOW_ITEM_TYPE_UDP,
+	RTE_FLOW_ITEM_TYPE_L2TPV2,
+	RTE_FLOW_ITEM_TYPE_PPP,
+	RTE_FLOW_ITEM_TYPE_IPV4,
+	RTE_FLOW_ITEM_TYPE_TCP,
+	RTE_FLOW_ITEM_TYPE_END,
+};
+
+enum rte_flow_item_type iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv6_udp[] = {
+	RTE_FLOW_ITEM_TYPE_ETH,
+	RTE_FLOW_ITEM_TYPE_IPV6,
+	RTE_FLOW_ITEM_TYPE_UDP,
+	RTE_FLOW_ITEM_TYPE_L2TPV2,
+	RTE_FLOW_ITEM_TYPE_PPP,
+	RTE_FLOW_ITEM_TYPE_IPV6,
+	RTE_FLOW_ITEM_TYPE_UDP,
+	RTE_FLOW_ITEM_TYPE_END,
+};
+
+enum rte_flow_item_type iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv6_tcp[] = {
+	RTE_FLOW_ITEM_TYPE_ETH,
+	RTE_FLOW_ITEM_TYPE_IPV6,
+	RTE_FLOW_ITEM_TYPE_UDP,
+	RTE_FLOW_ITEM_TYPE_L2TPV2,
+	RTE_FLOW_ITEM_TYPE_PPP,
+	RTE_FLOW_ITEM_TYPE_IPV6,
+	RTE_FLOW_ITEM_TYPE_TCP,
+	RTE_FLOW_ITEM_TYPE_END,
+};
+
+
+
 typedef struct iavf_flow_engine * (*parse_engine_t)(struct iavf_adapter *ad,
 		struct rte_flow *flow,
 		struct iavf_parser_list *parser_list,
diff --git a/drivers/net/iavf/iavf_generic_flow.h b/drivers/net/iavf/iavf_generic_flow.h
index 4794d1fb80..f2b54e1944 100644
--- a/drivers/net/iavf/iavf_generic_flow.h
+++ b/drivers/net/iavf/iavf_generic_flow.h
@@ -410,6 +410,21 @@ extern enum rte_flow_item_type iavf_pattern_eth_ipv6_gre_ipv6_tcp[];
 extern enum rte_flow_item_type iavf_pattern_eth_ipv6_gre_ipv4_udp[];
 extern enum rte_flow_item_type iavf_pattern_eth_ipv6_gre_ipv6_udp[];
 
+/* PPPoL2TPv2oUDP */
+extern enum rte_flow_item_type iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv4[];
+extern enum rte_flow_item_type iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv6[];
+extern enum rte_flow_item_type iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv4_udp[];
+extern enum rte_flow_item_type iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv4_tcp[];
+extern enum rte_flow_item_type iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv6_udp[];
+extern enum rte_flow_item_type iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv6_tcp[];
+extern enum rte_flow_item_type iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv4[];
+extern enum rte_flow_item_type iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv6[];
+extern enum rte_flow_item_type iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv4_udp[];
+extern enum rte_flow_item_type iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv4_tcp[];
+extern enum rte_flow_item_type iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv6_udp[];
+extern enum rte_flow_item_type iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv6_tcp[];
+
+
 extern const struct rte_flow_ops iavf_flow_ops;
 
 /* pattern structure */
diff --git a/drivers/net/iavf/iavf_hash.c b/drivers/net/iavf/iavf_hash.c
index 1f2d3772d1..9e7286861e 100644
--- a/drivers/net/iavf/iavf_hash.c
+++ b/drivers/net/iavf/iavf_hash.c
@@ -34,6 +34,8 @@
 /* the second IP header of GTPoGRE */
 #define IAVF_PHINT_MID_IPV4			BIT_ULL(7)
 #define IAVF_PHINT_MID_IPV6			BIT_ULL(8)
+/* L2TPV2 */
+#define IAVF_PHINT_L2TPV2			BIT_ULL(9)
 
 #define IAVF_PHINT_GTPU_MSK	(IAVF_PHINT_GTPU	| \
 				 IAVF_PHINT_GTPU_EH	| \
@@ -164,6 +166,12 @@ iavf_hash_parse_pattern_action(struct iavf_adapter *ad,
 	VIRTCHNL_PROTO_HDR_ECPRI, \
 	FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_ECPRI_PC_RTC_ID), {BUFF_NOUSED} }
 
+#define proto_hdr_l2tpv2 { \
+	VIRTCHNL_PROTO_HDR_L2TPV2, 0, {BUFF_NOUSED} }
+
+#define proto_hdr_ppp { \
+	VIRTCHNL_PROTO_HDR_PPP, 0, {BUFF_NOUSED} }
+
 #define TUNNEL_LEVEL_OUTER		0
 #define TUNNEL_LEVEL_INNER		1
 
@@ -338,6 +346,52 @@ struct virtchnl_proto_hdrs ipv4_ecpri_tmplt = {
 	TUNNEL_LEVEL_OUTER, 3, {proto_hdr_ipv4, proto_hdr_udp, proto_hdr_ecpri}
 };
 
+struct virtchnl_proto_hdrs udp_l2tpv2_ppp_ipv4_tmplt = {
+	TUNNEL_LEVEL_INNER, 3,
+	{proto_hdr_l2tpv2,
+	 proto_hdr_ppp,
+	 proto_hdr_ipv4}
+};
+
+struct virtchnl_proto_hdrs udp_l2tpv2_ppp_ipv6_tmplt = {
+	TUNNEL_LEVEL_INNER, 3,
+	{proto_hdr_l2tpv2,
+	 proto_hdr_ppp,
+	 proto_hdr_ipv6}
+};
+
+struct virtchnl_proto_hdrs udp_l2tpv2_ppp_ipv4_udp_tmplt = {
+	TUNNEL_LEVEL_INNER, 4,
+	{proto_hdr_l2tpv2,
+	 proto_hdr_ppp,
+	 proto_hdr_ipv4_with_prot,
+	 proto_hdr_udp}
+};
+
+struct virtchnl_proto_hdrs udp_l2tpv2_ppp_ipv4_tcp_tmplt = {
+	TUNNEL_LEVEL_INNER, 4,
+	{proto_hdr_l2tpv2,
+	 proto_hdr_ppp,
+	 proto_hdr_ipv4_with_prot,
+	 proto_hdr_tcp}
+};
+
+struct virtchnl_proto_hdrs udp_l2tpv2_ppp_ipv6_udp_tmplt = {
+	TUNNEL_LEVEL_INNER, 4,
+	{proto_hdr_l2tpv2,
+	 proto_hdr_ppp,
+	 proto_hdr_ipv6_with_prot,
+	 proto_hdr_udp}
+};
+
+struct virtchnl_proto_hdrs udp_l2tpv2_ppp_ipv6_tcp_tmplt = {
+	TUNNEL_LEVEL_INNER, 4,
+	{proto_hdr_l2tpv2,
+	 proto_hdr_ppp,
+	 proto_hdr_ipv6_with_prot,
+	 proto_hdr_tcp}
+};
+
 /* rss type super set */
 
 /* IPv4 outer */
@@ -493,6 +547,13 @@ static struct iavf_pattern_match_item iavf_hash_pattern_list[] = {
 	{iavf_pattern_eth_ipv6_gre_ipv4_tcp,	IAVF_RSS_TYPE_INNER_IPV4_TCP, &inner_ipv4_tcp_tmplt},
 	{iavf_pattern_eth_ipv4_gre_ipv4_udp,	IAVF_RSS_TYPE_INNER_IPV4_UDP, &inner_ipv4_udp_tmplt},
 	{iavf_pattern_eth_ipv6_gre_ipv4_udp,	IAVF_RSS_TYPE_INNER_IPV4_UDP, &inner_ipv4_udp_tmplt},
+	{iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv4,	IAVF_RSS_TYPE_INNER_IPV4,	&udp_l2tpv2_ppp_ipv4_tmplt},
+	{iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv4_udp,	IAVF_RSS_TYPE_INNER_IPV4_UDP,	&udp_l2tpv2_ppp_ipv4_udp_tmplt},
+	{iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv4_tcp,	IAVF_RSS_TYPE_INNER_IPV4_TCP,	&udp_l2tpv2_ppp_ipv4_tcp_tmplt},
+	{iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv4,	IAVF_RSS_TYPE_INNER_IPV4,	&udp_l2tpv2_ppp_ipv4_tmplt},
+	{iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv4_udp,	IAVF_RSS_TYPE_INNER_IPV4_UDP,	&udp_l2tpv2_ppp_ipv4_udp_tmplt},
+	{iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv4_tcp,	IAVF_RSS_TYPE_INNER_IPV4_TCP,	&udp_l2tpv2_ppp_ipv4_tcp_tmplt},
+
 	/* IPv6 */
 	{iavf_pattern_eth_ipv6,				IAVF_RSS_TYPE_OUTER_IPV6,	&outer_ipv6_tmplt},
 	{iavf_pattern_eth_ipv6_frag_ext,		IAVF_RSS_TYPE_OUTER_IPV6_FRAG,	&outer_ipv6_frag_tmplt},
@@ -553,6 +614,13 @@ static struct iavf_pattern_match_item iavf_hash_pattern_list[] = {
 	{iavf_pattern_eth_ipv6_gre_ipv6_tcp,	IAVF_RSS_TYPE_INNER_IPV6_TCP, &inner_ipv6_tcp_tmplt},
 	{iavf_pattern_eth_ipv4_gre_ipv6_udp,	IAVF_RSS_TYPE_INNER_IPV6_UDP, &inner_ipv6_udp_tmplt},
 	{iavf_pattern_eth_ipv6_gre_ipv6_udp,	IAVF_RSS_TYPE_INNER_IPV6_UDP, &inner_ipv6_udp_tmplt},
+	{iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv6,	IAVF_RSS_TYPE_INNER_IPV6,	&udp_l2tpv2_ppp_ipv6_tmplt},
+	{iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv6_udp,	IAVF_RSS_TYPE_INNER_IPV6_UDP,	&udp_l2tpv2_ppp_ipv6_udp_tmplt},
+	{iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv6_tcp,	IAVF_RSS_TYPE_INNER_IPV6_TCP,	&udp_l2tpv2_ppp_ipv6_tcp_tmplt},
+	{iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv6,	IAVF_RSS_TYPE_INNER_IPV6,	&udp_l2tpv2_ppp_ipv6_tmplt},
+	{iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv6_udp,	IAVF_RSS_TYPE_INNER_IPV6_UDP,	&udp_l2tpv2_ppp_ipv6_udp_tmplt},
+	{iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv6_tcp,	IAVF_RSS_TYPE_INNER_IPV6_TCP,	&udp_l2tpv2_ppp_ipv6_tcp_tmplt},
+
 };
 
 static struct iavf_flow_engine iavf_hash_engine = {
@@ -687,13 +755,17 @@ iavf_hash_parse_pattern(const struct rte_flow_item pattern[], uint64_t *phint,
 
 		switch (item->type) {
 		case RTE_FLOW_ITEM_TYPE_IPV4:
-			if (!(*phint & IAVF_PHINT_GTPU_MSK) && !(*phint & IAVF_PHINT_GRE))
+			if (!(*phint & IAVF_PHINT_GTPU_MSK) &&
+			    !(*phint & IAVF_PHINT_GRE) &&
+			    !(*phint & IAVF_PHINT_L2TPV2))
 				*phint |= IAVF_PHINT_OUTER_IPV4;
 			if ((*phint & IAVF_PHINT_GRE) && !(*phint & IAVF_PHINT_GTPU_MSK))
 				*phint |= IAVF_PHINT_MID_IPV4;
 			break;
 		case RTE_FLOW_ITEM_TYPE_IPV6:
-			if (!(*phint & IAVF_PHINT_GTPU_MSK) && !(*phint & IAVF_PHINT_GRE))
+			if (!(*phint & IAVF_PHINT_GTPU_MSK) &&
+			    !(*phint & IAVF_PHINT_GRE) &&
+			    !(*phint & IAVF_PHINT_L2TPV2))
 				*phint |= IAVF_PHINT_OUTER_IPV6;
 			if ((*phint & IAVF_PHINT_GRE) && !(*phint & IAVF_PHINT_GTPU_MSK))
 				*phint |= IAVF_PHINT_MID_IPV6;
@@ -728,6 +800,10 @@ iavf_hash_parse_pattern(const struct rte_flow_item pattern[], uint64_t *phint,
 			break;
 		case RTE_FLOW_ITEM_TYPE_GRE:
 			*phint |= IAVF_PHINT_GRE;
+			break;
+		case RTE_FLOW_ITEM_TYPE_L2TPV2:
+			*phint |= IAVF_PHINT_L2TPV2;
+			break;
 		default:
 			break;
 		}
@@ -1050,12 +1126,40 @@ iavf_refine_proto_hdrs_by_pattern(struct virtchnl_proto_hdrs *proto_hdrs,
 	proto_hdrs->tunnel_level = tun_lvl;
 }
 
+static void
+iavf_refine_proto_hdrs_l2tpv2(struct virtchnl_proto_hdrs *proto_hdrs,
+			      uint64_t phint)
+{
+	struct virtchnl_proto_hdr *hdr1;
+	int i;
+
+	if (!(phint & IAVF_PHINT_L2TPV2))
+		return;
+
+	if (proto_hdrs->tunnel_level == TUNNEL_LEVEL_INNER) {
+		/* shift headers layer */
+		for (i = proto_hdrs->count - 1 + 1; i > 0; i--)
+			proto_hdrs->proto_hdr[i] = proto_hdrs->proto_hdr[i - 1];
+
+		/* adding outer ip header at layer 0 */
+		hdr1 = &proto_hdrs->proto_hdr[0];
+		hdr1->field_selector = 0;
+		proto_hdrs->count++;
+		proto_hdrs->tunnel_level = TUNNEL_LEVEL_OUTER;
+		if (phint & IAVF_PHINT_OUTER_IPV4)
+			VIRTCHNL_SET_PROTO_HDR_TYPE(hdr1, IPV4);
+		else if (phint & IAVF_PHINT_OUTER_IPV6)
+			VIRTCHNL_SET_PROTO_HDR_TYPE(hdr1, IPV6);
+	}
+}
+
 static void iavf_refine_proto_hdrs(struct virtchnl_proto_hdrs *proto_hdrs,
 				   uint64_t rss_type, uint64_t phint)
 {
 	iavf_refine_proto_hdrs_l234(proto_hdrs, rss_type);
 	iavf_refine_proto_hdrs_by_pattern(proto_hdrs, phint);
 	iavf_refine_proto_hdrs_gtpu(proto_hdrs, rss_type);
+	iavf_refine_proto_hdrs_l2tpv2(proto_hdrs, phint);
 }
 
 static uint64_t invalid_rss_comb[] = {
-- 
2.25.1


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

* [dpdk-dev] [PATCH v3 3/3] app/testpmd: support L2TPV2 and PPP protocol pattern
  2021-10-15  9:58   ` [dpdk-dev] [PATCH v3 0/3] " Jie Wang
  2021-10-15  9:58     ` [dpdk-dev] [PATCH v3 1/3] ethdev: support PPP and L2TPV2 procotol Jie Wang
  2021-10-15  9:58     ` [dpdk-dev] [PATCH v3 2/3] net/iavf: support PPPoL2TPv2oUDP RSS Hash Jie Wang
@ 2021-10-15  9:58     ` Jie Wang
  2021-10-17  8:51       ` Ori Kam
  2021-10-18  9:33     ` [dpdk-dev] [PATCH v4 0/3] support PPPoL2TPv2oUDP RSS Hash Jie Wang
  3 siblings, 1 reply; 71+ messages in thread
From: Jie Wang @ 2021-10-15  9:58 UTC (permalink / raw)
  To: dev
  Cc: orika, ferruh.yigit, thomas, andrew.rybchenko, xiaoyun.li,
	stevex.yang, jingjing.wu, beilei.xing, wenjun1.wu, Jie Wang

Add support for test-pmd to parse protocol pattern L2TPv2 and PPP.

Signed-off-by: Wenjun Wu <wenjun1.wu@intel.com>
Signed-off-by: Jie Wang <jie1x.wang@intel.com>
---
 app/test-pmd/cmdline.c      | 244 ++++++++++++++++++++++
 app/test-pmd/cmdline_flow.c | 396 ++++++++++++++++++++++++++++++++++++
 app/test-pmd/testpmd.h      |  22 ++
 3 files changed, 662 insertions(+)

diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index 36d50fd3c7..bba761ad4b 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -13300,6 +13300,247 @@ cmdline_parse_inst_t cmd_set_nvgre_with_vlan = {
 	},
 };
 
+/** Set L2TPV2 encapsulation details */
+struct cmd_set_l2tpv2_result {
+	cmdline_fixed_string_t set;
+	cmdline_fixed_string_t l2tpv2;
+	cmdline_fixed_string_t pos_token;
+	cmdline_fixed_string_t ip_version;
+	uint32_t vlan_present:1;
+	uint16_t flags_version;
+	uint16_t session_id;
+	uint16_t udp_src;
+	uint16_t udp_dst;
+	cmdline_ipaddr_t ip_src;
+	cmdline_ipaddr_t ip_dst;
+	uint16_t tci;
+	uint8_t tos;
+	uint8_t ttl;
+	struct rte_ether_addr eth_src;
+	struct rte_ether_addr eth_dst;
+};
+
+cmdline_parse_token_string_t cmd_set_l2tpv2_set =
+	TOKEN_STRING_INITIALIZER(struct cmd_set_l2tpv2_result, set, "set");
+cmdline_parse_token_string_t cmd_set_l2tpv2_l2tpv2 =
+	TOKEN_STRING_INITIALIZER(struct cmd_set_l2tpv2_result, l2tpv2, "l2tpv2");
+cmdline_parse_token_string_t cmd_set_l2tpv2_l2tpv2_tos_ttl =
+	TOKEN_STRING_INITIALIZER(struct cmd_set_l2tpv2_result, l2tpv2,
+				 "l2tpv2-tos-ttl");
+cmdline_parse_token_string_t cmd_set_l2tpv2_l2tpv2_with_vlan =
+	TOKEN_STRING_INITIALIZER(struct cmd_set_l2tpv2_result, l2tpv2,
+				 "l2tpv2-with-vlan");
+cmdline_parse_token_string_t cmd_set_l2tpv2_ip_version =
+	TOKEN_STRING_INITIALIZER(struct cmd_set_l2tpv2_result, pos_token,
+				 "ip-version");
+cmdline_parse_token_string_t cmd_set_l2tpv2_ip_version_value =
+	TOKEN_STRING_INITIALIZER(struct cmd_set_l2tpv2_result, ip_version,
+				 "ipv4#ipv6");
+cmdline_parse_token_string_t cmd_set_l2tpv2_flags_version =
+	TOKEN_STRING_INITIALIZER(struct cmd_set_l2tpv2_result, pos_token,
+				 "flags_version");
+cmdline_parse_token_num_t cmd_set_l2tpv2_flags_version_value =
+	TOKEN_NUM_INITIALIZER(struct cmd_set_l2tpv2_result, flags_version,
+			      RTE_UINT16);
+cmdline_parse_token_string_t cmd_set_l2tpv2_session_id =
+	TOKEN_STRING_INITIALIZER(struct cmd_set_l2tpv2_result, pos_token,
+				 "session_id");
+cmdline_parse_token_num_t cmd_set_l2tpv2_session_id_value =
+	TOKEN_NUM_INITIALIZER(struct cmd_set_l2tpv2_result, session_id,
+			      RTE_UINT16);
+cmdline_parse_token_string_t cmd_set_l2tpv2_udp_src =
+	TOKEN_STRING_INITIALIZER(struct cmd_set_l2tpv2_result, pos_token,
+				 "udp-src");
+cmdline_parse_token_num_t cmd_set_l2tpv2_udp_src_value =
+	TOKEN_NUM_INITIALIZER(struct cmd_set_l2tpv2_result, udp_src,
+			      RTE_UINT16);
+cmdline_parse_token_string_t cmd_set_l2tpv2_udp_dst =
+	TOKEN_STRING_INITIALIZER(struct cmd_set_l2tpv2_result, pos_token,
+				 "udp-dst");
+cmdline_parse_token_num_t cmd_set_l2tpv2_udp_dst_value =
+	TOKEN_NUM_INITIALIZER(struct cmd_set_l2tpv2_result, udp_dst,
+			      RTE_UINT16);
+cmdline_parse_token_string_t cmd_set_l2tpv2_ip_tos =
+	TOKEN_STRING_INITIALIZER(struct cmd_set_l2tpv2_result, pos_token,
+				 "ip-tos");
+cmdline_parse_token_num_t cmd_set_l2tpv2_ip_tos_value =
+	TOKEN_NUM_INITIALIZER(struct cmd_set_l2tpv2_result, tos, RTE_UINT8);
+cmdline_parse_token_string_t cmd_set_l2tpv2_ip_ttl =
+	TOKEN_STRING_INITIALIZER(struct cmd_set_l2tpv2_result, pos_token,
+				 "ip-ttl");
+cmdline_parse_token_num_t cmd_set_l2tpv2_ip_ttl_value =
+	TOKEN_NUM_INITIALIZER(struct cmd_set_l2tpv2_result, ttl, RTE_UINT8);
+cmdline_parse_token_string_t cmd_set_l2tpv2_ip_src =
+	TOKEN_STRING_INITIALIZER(struct cmd_set_l2tpv2_result, pos_token,
+				 "ip-src");
+cmdline_parse_token_ipaddr_t cmd_set_l2tpv2_ip_src_value =
+	TOKEN_IPADDR_INITIALIZER(struct cmd_set_l2tpv2_result, ip_src);
+cmdline_parse_token_string_t cmd_set_l2tpv2_ip_dst =
+	TOKEN_STRING_INITIALIZER(struct cmd_set_l2tpv2_result, pos_token,
+				 "ip-dst");
+cmdline_parse_token_ipaddr_t cmd_set_l2tpv2_ip_dst_value =
+	TOKEN_IPADDR_INITIALIZER(struct cmd_set_l2tpv2_result, ip_dst);
+cmdline_parse_token_string_t cmd_set_l2tpv2_vlan =
+	TOKEN_STRING_INITIALIZER(struct cmd_set_l2tpv2_result, pos_token,
+				 "vlan-tci");
+cmdline_parse_token_num_t cmd_set_l2tpv2_vlan_value =
+	TOKEN_NUM_INITIALIZER(struct cmd_set_l2tpv2_result, tci, RTE_UINT16);
+cmdline_parse_token_string_t cmd_set_l2tpv2_eth_src =
+	TOKEN_STRING_INITIALIZER(struct cmd_set_l2tpv2_result, pos_token,
+				 "eth-src");
+cmdline_parse_token_etheraddr_t cmd_set_l2tpv2_eth_src_value =
+	TOKEN_ETHERADDR_INITIALIZER(struct cmd_set_l2tpv2_result, eth_src);
+cmdline_parse_token_string_t cmd_set_l2tpv2_eth_dst =
+	TOKEN_STRING_INITIALIZER(struct cmd_set_l2tpv2_result, pos_token,
+				 "eth-dst");
+cmdline_parse_token_etheraddr_t cmd_set_l2tpv2_eth_dst_value =
+	TOKEN_ETHERADDR_INITIALIZER(struct cmd_set_l2tpv2_result, eth_dst);
+
+static void cmd_set_l2tpv2_parsed(void *parsed_result,
+	__rte_unused struct cmdline *cl,
+	__rte_unused void *data)
+{
+	struct cmd_set_l2tpv2_result *res = parsed_result;
+
+	l2tpv2_encap_conf.select_tos_ttl = 0;
+	if (strcmp(res->l2tpv2, "l2tpv2") == 0)
+		l2tpv2_encap_conf.select_vlan = 0;
+	else if (strcmp(res->l2tpv2, "l2tpv2-with-vlan") == 0)
+		l2tpv2_encap_conf.select_vlan = 1;
+	else if (strcmp(res->l2tpv2, "l2tpv2-tos-ttl") == 0) {
+		l2tpv2_encap_conf.select_vlan = 0;
+		l2tpv2_encap_conf.select_tos_ttl = 1;
+	}
+	if (strcmp(res->ip_version, "ipv4") == 0)
+		l2tpv2_encap_conf.select_ipv4 = 1;
+	else if (strcmp(res->ip_version, "ipv6") == 0)
+		l2tpv2_encap_conf.select_ipv4 = 0;
+	else
+		return;
+
+	l2tpv2_encap_conf.flags_version = res->flags_version;
+	l2tpv2_encap_conf.session_id = res->session_id;
+	l2tpv2_encap_conf.udp_src = res->udp_src;
+	l2tpv2_encap_conf.udp_dst = res->udp_dst;
+	l2tpv2_encap_conf.ip_tos = res->tos;
+	l2tpv2_encap_conf.ip_ttl = res->ttl;
+	if (l2tpv2_encap_conf.select_ipv4) {
+		IPV4_ADDR_TO_UINT(res->ip_src, l2tpv2_encap_conf.ipv4_src);
+		IPV4_ADDR_TO_UINT(res->ip_dst, l2tpv2_encap_conf.ipv4_dst);
+	} else {
+		IPV6_ADDR_TO_ARRAY(res->ip_src, l2tpv2_encap_conf.ipv6_src);
+		IPV6_ADDR_TO_ARRAY(res->ip_dst, l2tpv2_encap_conf.ipv6_dst);
+	}
+	if (l2tpv2_encap_conf.select_vlan)
+		l2tpv2_encap_conf.vlan_tci = rte_cpu_to_be_16(res->tci);
+	rte_memcpy(l2tpv2_encap_conf.eth_src, res->eth_src.addr_bytes,
+		   RTE_ETHER_ADDR_LEN);
+	rte_memcpy(l2tpv2_encap_conf.eth_dst, res->eth_dst.addr_bytes,
+		   RTE_ETHER_ADDR_LEN);
+}
+
+cmdline_parse_inst_t cmd_set_l2tpv2 = {
+	.f = cmd_set_l2tpv2_parsed,
+	.data = NULL,
+	.help_str = "set l2tpv2 ip-version ipv4|ipv6 flags_version"
+		" <flags_version> session_id <session_id> udp-src <udp-src>"
+		" udp-dst <udp-dst> ip-src <ip-src> ip-dst <ip-dst> eth-src"
+		" <eth-src> eth-dst <eth-dst>",
+	.tokens = {
+		(void *)&cmd_set_l2tpv2_set,
+		(void *)&cmd_set_l2tpv2_l2tpv2,
+		(void *)&cmd_set_l2tpv2_ip_version,
+		(void *)&cmd_set_l2tpv2_ip_version_value,
+		(void *)&cmd_set_l2tpv2_flags_version,
+		(void *)&cmd_set_l2tpv2_flags_version_value,
+		(void *)&cmd_set_l2tpv2_session_id,
+		(void *)&cmd_set_l2tpv2_session_id_value,
+		(void *)&cmd_set_l2tpv2_udp_src,
+		(void *)&cmd_set_l2tpv2_udp_src_value,
+		(void *)&cmd_set_l2tpv2_udp_dst,
+		(void *)&cmd_set_l2tpv2_udp_dst_value,
+		(void *)&cmd_set_l2tpv2_ip_src,
+		(void *)&cmd_set_l2tpv2_ip_src_value,
+		(void *)&cmd_set_l2tpv2_ip_dst,
+		(void *)&cmd_set_l2tpv2_ip_dst_value,
+		(void *)&cmd_set_l2tpv2_eth_src,
+		(void *)&cmd_set_l2tpv2_eth_src_value,
+		(void *)&cmd_set_l2tpv2_eth_dst,
+		(void *)&cmd_set_l2tpv2_eth_dst_value,
+		NULL,
+	},
+};
+
+cmdline_parse_inst_t cmd_set_l2tpv2_tos_ttl = {
+	.f = cmd_set_l2tpv2_parsed,
+	.data = NULL,
+	.help_str = "set l2tpv2-tos-ttl ip-version ipv4|ipv6 flags_version"
+		" <flags_version> session_id <session_id> udp-src <udp-src>"
+		" udp-dst <udp-dst> ip-tos <ip-tos> ip-ttl <ip-ttl> ip-src"
+		" <ip-src> ip-dst <ip-dst> eth-src <eth-src> eth-dst <eth-dst>",
+	.tokens = {
+		(void *)&cmd_set_l2tpv2_set,
+		(void *)&cmd_set_l2tpv2_l2tpv2_tos_ttl,
+		(void *)&cmd_set_l2tpv2_ip_version,
+		(void *)&cmd_set_l2tpv2_ip_version_value,
+		(void *)&cmd_set_l2tpv2_flags_version,
+		(void *)&cmd_set_l2tpv2_flags_version_value,
+		(void *)&cmd_set_l2tpv2_session_id,
+		(void *)&cmd_set_l2tpv2_session_id_value,
+		(void *)&cmd_set_l2tpv2_udp_src,
+		(void *)&cmd_set_l2tpv2_udp_src_value,
+		(void *)&cmd_set_l2tpv2_udp_dst,
+		(void *)&cmd_set_l2tpv2_udp_dst_value,
+		(void *)&cmd_set_l2tpv2_ip_tos,
+		(void *)&cmd_set_l2tpv2_ip_tos_value,
+		(void *)&cmd_set_l2tpv2_ip_ttl,
+		(void *)&cmd_set_l2tpv2_ip_ttl_value,
+		(void *)&cmd_set_l2tpv2_ip_src,
+		(void *)&cmd_set_l2tpv2_ip_src_value,
+		(void *)&cmd_set_l2tpv2_ip_dst,
+		(void *)&cmd_set_l2tpv2_ip_dst_value,
+		(void *)&cmd_set_l2tpv2_eth_src,
+		(void *)&cmd_set_l2tpv2_eth_src_value,
+		(void *)&cmd_set_l2tpv2_eth_dst,
+		(void *)&cmd_set_l2tpv2_eth_dst_value,
+		NULL,
+	},
+};
+
+cmdline_parse_inst_t cmd_set_l2tpv2_with_vlan = {
+	.f = cmd_set_l2tpv2_parsed,
+	.data = NULL,
+	.help_str = "set l2tpv2-with-vlan ip-version ipv4|ipv6 flags_version"
+		" <flags_version> session_id <session_id> udp-src <udp-src>"
+		" udp-dst <udp-dst> ip-src <ip-src> ip-dst <ip-dst> vlan-tci"
+		" <vlan-tci> eth-src <eth-src> eth-dst <eth-dst>",
+	.tokens = {
+		(void *)&cmd_set_l2tpv2_set,
+		(void *)&cmd_set_l2tpv2_l2tpv2_with_vlan,
+		(void *)&cmd_set_l2tpv2_ip_version,
+		(void *)&cmd_set_l2tpv2_ip_version_value,
+		(void *)&cmd_set_l2tpv2_flags_version,
+		(void *)&cmd_set_l2tpv2_flags_version_value,
+		(void *)&cmd_set_l2tpv2_session_id,
+		(void *)&cmd_set_l2tpv2_session_id_value,
+		(void *)&cmd_set_l2tpv2_udp_src,
+		(void *)&cmd_set_l2tpv2_udp_src_value,
+		(void *)&cmd_set_l2tpv2_udp_dst,
+		(void *)&cmd_set_l2tpv2_udp_dst_value,
+		(void *)&cmd_set_l2tpv2_ip_src,
+		(void *)&cmd_set_l2tpv2_ip_src_value,
+		(void *)&cmd_set_l2tpv2_ip_dst,
+		(void *)&cmd_set_l2tpv2_ip_dst_value,
+		(void *)&cmd_set_l2tpv2_vlan,
+		(void *)&cmd_set_l2tpv2_vlan_value,
+		(void *)&cmd_set_l2tpv2_eth_src,
+		(void *)&cmd_set_l2tpv2_eth_src_value,
+		(void *)&cmd_set_l2tpv2_eth_dst,
+		(void *)&cmd_set_l2tpv2_eth_dst_value,
+		NULL,
+	},
+};
+
 /** Set L2 encapsulation details */
 struct cmd_set_l2_encap_result {
 	cmdline_fixed_string_t set;
@@ -17774,6 +18015,9 @@ cmdline_parse_ctx_t main_ctx[] = {
 	(cmdline_parse_inst_t *)&cmd_set_vxlan_with_vlan,
 	(cmdline_parse_inst_t *)&cmd_set_nvgre,
 	(cmdline_parse_inst_t *)&cmd_set_nvgre_with_vlan,
+	(cmdline_parse_inst_t *)&cmd_set_l2tpv2,
+	(cmdline_parse_inst_t *)&cmd_set_l2tpv2_tos_ttl,
+	(cmdline_parse_inst_t *)&cmd_set_l2tpv2_with_vlan,
 	(cmdline_parse_inst_t *)&cmd_set_l2_encap,
 	(cmdline_parse_inst_t *)&cmd_set_l2_encap_with_vlan,
 	(cmdline_parse_inst_t *)&cmd_set_l2_decap,
diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
index 0b5856c7d5..4f73d4f39d 100644
--- a/app/test-pmd/cmdline_flow.c
+++ b/app/test-pmd/cmdline_flow.c
@@ -306,6 +306,23 @@ enum index {
 	ITEM_POL_PORT,
 	ITEM_POL_METER,
 	ITEM_POL_POLICY,
+	ITEM_L2TPV2,
+	ITEM_L2TPV2_COMMON,
+	ITEM_L2TPV2_COMMON_TYPE,
+	ITEM_L2TPV2_COMMON_TYPE_DATA_L,
+	ITEM_L2TPV2_COMMON_TYPE_CTRL,
+	ITEM_L2TPV2_MSG_DATA_L_LENGTH,
+	ITEM_L2TPV2_MSG_DATA_L_TUNNEL_ID,
+	ITEM_L2TPV2_MSG_DATA_L_SESSION_ID,
+	ITEM_L2TPV2_MSG_CTRL_LENGTH,
+	ITEM_L2TPV2_MSG_CTRL_TUNNEL_ID,
+	ITEM_L2TPV2_MSG_CTRL_SESSION_ID,
+	ITEM_L2TPV2_MSG_CTRL_NS,
+	ITEM_L2TPV2_MSG_CTRL_NR,
+	ITEM_PPP,
+	ITEM_PPP_ADDR,
+	ITEM_PPP_CTRL,
+	ITEM_PPP_PROTO_ID,
 
 	/* Validate/create actions. */
 	ACTIONS,
@@ -376,6 +393,8 @@ enum index {
 	ACTION_VXLAN_DECAP,
 	ACTION_NVGRE_ENCAP,
 	ACTION_NVGRE_DECAP,
+	ACTION_L2TPV2_ENCAP,
+	ACTION_L2TPV2_DECAP,
 	ACTION_L2_ENCAP,
 	ACTION_L2_DECAP,
 	ACTION_MPLSOGRE_ENCAP,
@@ -581,6 +600,44 @@ struct action_nvgre_encap_data {
 	struct rte_flow_item_nvgre item_nvgre;
 };
 
+struct l2tpv2_encap_conf l2tpv2_encap_conf = {
+	.select_ipv4 = 1,
+	.select_vlan = 0,
+	.select_tos_ttl = 0,
+	.flags_version = 0,
+	.session_id = 0,
+	.udp_src = 0,
+	.udp_dst = 1701,
+	.ipv4_src = RTE_IPV4(127, 0, 0, 1),
+	.ipv4_dst = RTE_IPV4(255, 255, 255, 255),
+	.ipv6_src = "\x00\x00\x00\x00\x00\x00\x00\x00"
+		"\x00\x00\x00\x00\x00\x00\x00\x01",
+	.ipv6_dst = "\x00\x00\x00\x00\x00\x00\x00\x00"
+		"\x00\x00\x00\x00\x00\x00\x11\x11",
+	.vlan_tci = 0,
+	.ip_tos = 0,
+	.ip_ttl = 255,
+	.eth_src = "\x00\x00\x00\x00\x00\x00",
+	.eth_dst = "\xff\xff\xff\xff\xff\xff",
+};
+
+/** Maximum number of items in struct rte_flow_action_l2tpv2_encap. */
+#define ACTION_L2TPV2_ENCAP_ITEMS_NUM 6
+
+/** Storage for struct rte_flow_action_l2tpv2_encap including external data. */
+struct action_l2tpv2_encap_data {
+	struct rte_flow_action_l2tpv2_encap conf;
+	struct rte_flow_item items[ACTION_L2TPV2_ENCAP_ITEMS_NUM];
+	struct rte_flow_item_eth item_eth;
+	struct rte_flow_item_vlan item_vlan;
+	union {
+		struct rte_flow_item_ipv4 item_ipv4;
+		struct rte_flow_item_ipv6 item_ipv6;
+	};
+	struct rte_flow_item_udp item_udp;
+	struct rte_flow_item_l2tpv2 item_l2tpv2;
+};
+
 struct l2_encap_conf l2_encap_conf;
 
 struct l2_decap_conf l2_decap_conf;
@@ -614,6 +671,7 @@ struct rte_flow_action_port_id sample_port_id[RAW_SAMPLE_CONFS_MAX_NUM];
 struct rte_flow_action_raw_encap sample_encap[RAW_SAMPLE_CONFS_MAX_NUM];
 struct action_vxlan_encap_data sample_vxlan_encap[RAW_SAMPLE_CONFS_MAX_NUM];
 struct action_nvgre_encap_data sample_nvgre_encap[RAW_SAMPLE_CONFS_MAX_NUM];
+struct action_l2tpv2_encap_data sample_l2tpv2_encap[RAW_SAMPLE_CONFS_MAX_NUM];
 struct action_rss_data sample_rss_data[RAW_SAMPLE_CONFS_MAX_NUM];
 struct rte_flow_action_vf sample_vf[RAW_SAMPLE_CONFS_MAX_NUM];
 
@@ -999,6 +1057,8 @@ static const enum index next_item[] = {
 	ITEM_GENEVE_OPT,
 	ITEM_INTEGRITY,
 	ITEM_CONNTRACK,
+	ITEM_L2TPV2,
+	ITEM_PPP,
 	END_SET,
 	ZERO,
 };
@@ -1367,6 +1427,31 @@ static const enum index item_integrity_lv[] = {
 	ZERO,
 };
 
+static const enum index item_l2tpv2[] = {
+	ITEM_L2TPV2_COMMON,
+	ITEM_NEXT,
+	ZERO,
+};
+
+static const enum index item_l2tpv2_common[] = {
+	ITEM_L2TPV2_COMMON_TYPE,
+	ZERO,
+};
+
+static const enum index item_l2tpv2_common_type[] = {
+	ITEM_L2TPV2_COMMON_TYPE_DATA_L,
+	ITEM_L2TPV2_COMMON_TYPE_CTRL,
+	ZERO,
+};
+
+static const enum index item_ppp[] = {
+	ITEM_PPP_ADDR,
+	ITEM_PPP_CTRL,
+	ITEM_PPP_PROTO_ID,
+	ITEM_NEXT,
+	ZERO,
+};
+
 static const enum index next_action[] = {
 	ACTION_END,
 	ACTION_VOID,
@@ -1400,6 +1485,8 @@ static const enum index next_action[] = {
 	ACTION_VXLAN_DECAP,
 	ACTION_NVGRE_ENCAP,
 	ACTION_NVGRE_DECAP,
+	ACTION_L2TPV2_ENCAP,
+	ACTION_L2TPV2_DECAP,
 	ACTION_L2_ENCAP,
 	ACTION_L2_DECAP,
 	ACTION_MPLSOGRE_ENCAP,
@@ -1687,6 +1774,7 @@ static const enum index next_action_sample[] = {
 	ACTION_RAW_ENCAP,
 	ACTION_VXLAN_ENCAP,
 	ACTION_NVGRE_ENCAP,
+	ACTION_L2TPV2_ENCAP,
 	ACTION_NEXT,
 	ZERO,
 };
@@ -1757,6 +1845,9 @@ static int parse_vc_action_vxlan_encap(struct context *, const struct token *,
 static int parse_vc_action_nvgre_encap(struct context *, const struct token *,
 				       const char *, unsigned int, void *,
 				       unsigned int);
+static int parse_vc_action_l2tpv2_encap(struct context *, const struct token *,
+					const char *, unsigned int, void *,
+					unsigned int);
 static int parse_vc_action_l2_encap(struct context *, const struct token *,
 				    const char *, unsigned int, void *,
 				    unsigned int);
@@ -3606,6 +3697,136 @@ static const struct token token_list[] = {
 			     item_param),
 		.args = ARGS(ARGS_ENTRY(struct rte_flow_item_conntrack, flags)),
 	},
+	[ITEM_L2TPV2] = {
+		.name = "l2tpv2",
+		.help = "match l2tpv2 header",
+		.priv = PRIV_ITEM(L2TPV2, sizeof(struct rte_flow_item_l2tpv2)),
+		.next = NEXT(item_l2tpv2),
+		.call = parse_vc,
+	},
+	[ITEM_L2TPV2_COMMON] = {
+		.name = "common",
+		.help = "l2tpv2 common header",
+		.next = NEXT(item_l2tpv2_common),
+	},
+	[ITEM_L2TPV2_COMMON_TYPE] = {
+		.name = "type",
+		.help = "type of common header",
+		.next = NEXT(item_l2tpv2_common_type),
+		.args = ARGS(ARG_ENTRY_HTON(struct rte_flow_item_l2tpv2)),
+	},
+	[ITEM_L2TPV2_COMMON_TYPE_DATA_L] = {
+		.name = "data_l",
+		.help = "Type #6: data message with length option",
+		.next = NEXT(NEXT_ENTRY(ITEM_L2TPV2_MSG_DATA_L_LENGTH,
+					ITEM_L2TPV2_MSG_DATA_L_TUNNEL_ID,
+					ITEM_L2TPV2_MSG_DATA_L_SESSION_ID,
+					ITEM_NEXT)),
+		.call = parse_vc,
+	},
+	[ITEM_L2TPV2_MSG_DATA_L_LENGTH] = {
+		.name = "length",
+		.help = "message length",
+		.next = NEXT(item_l2tpv2, NEXT_ENTRY(COMMON_UNSIGNED),
+			     item_param),
+		.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2,
+					     hdr.type7.tunnel_id)),
+	},
+	[ITEM_L2TPV2_MSG_DATA_L_TUNNEL_ID] = {
+		.name = "tunnel_id",
+		.help = "tunnel identifier",
+		.next = NEXT(item_l2tpv2, NEXT_ENTRY(COMMON_UNSIGNED),
+			     item_param),
+		.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2,
+					     hdr.type7.tunnel_id)),
+	},
+	[ITEM_L2TPV2_MSG_DATA_L_SESSION_ID] = {
+		.name = "session_id",
+		.help = "session identifier",
+		.next = NEXT(item_l2tpv2, NEXT_ENTRY(COMMON_UNSIGNED),
+			     item_param),
+		.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2,
+					     hdr.type7.session_id)),
+	},
+	[ITEM_L2TPV2_COMMON_TYPE_CTRL] = {
+		.name = "control",
+		.help = "Type #3: conrtol message contains length, ns, nr options",
+		.next = NEXT(NEXT_ENTRY(ITEM_L2TPV2_MSG_CTRL_LENGTH,
+					ITEM_L2TPV2_MSG_CTRL_TUNNEL_ID,
+					ITEM_L2TPV2_MSG_CTRL_SESSION_ID,
+					ITEM_L2TPV2_MSG_CTRL_NS,
+					ITEM_L2TPV2_MSG_CTRL_NR,
+					ITEM_NEXT)),
+		.call = parse_vc,
+	},
+	[ITEM_L2TPV2_MSG_CTRL_LENGTH] = {
+		.name = "length",
+		.help = "message length",
+		.next = NEXT(item_l2tpv2, NEXT_ENTRY(COMMON_UNSIGNED),
+			     item_param),
+		.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2,
+					     hdr.type3.length)),
+	},
+	[ITEM_L2TPV2_MSG_CTRL_TUNNEL_ID] = {
+		.name = "tunnel_id",
+		.help = "tunnel identifier",
+		.next = NEXT(item_l2tpv2, NEXT_ENTRY(COMMON_UNSIGNED),
+			     item_param),
+		.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2,
+					     hdr.type3.tunnel_id)),
+	},
+	[ITEM_L2TPV2_MSG_CTRL_SESSION_ID] = {
+		.name = "session_id",
+		.help = "session identifier",
+		.next = NEXT(item_l2tpv2, NEXT_ENTRY(COMMON_UNSIGNED),
+			     item_param),
+		.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2,
+					     hdr.type3.session_id)),
+	},
+	[ITEM_L2TPV2_MSG_CTRL_NS] = {
+		.name = "ns",
+		.help = "sequence number for message",
+		.next = NEXT(item_l2tpv2, NEXT_ENTRY(COMMON_UNSIGNED),
+			     item_param),
+		.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2,
+					     hdr.type3.ns)),
+	},
+	[ITEM_L2TPV2_MSG_CTRL_NR] = {
+		.name = "nr",
+		.help = "sequence number for next receive message",
+		.next = NEXT(item_l2tpv2, NEXT_ENTRY(COMMON_UNSIGNED),
+			     item_param),
+		.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2,
+					     hdr.type3.nr)),
+	},
+	[ITEM_PPP] = {
+		.name = "ppp",
+		.help = "match ppp header",
+		.priv = PRIV_ITEM(PPP, sizeof(struct rte_flow_item_ppp)),
+		.next = NEXT(item_ppp),
+		.call = parse_vc,
+	},
+	[ITEM_PPP_ADDR] = {
+		.name = "addr",
+		.help = "ppp address",
+		.next = NEXT(item_ppp, NEXT_ENTRY(COMMON_UNSIGNED),
+			     item_param),
+		.args = ARGS(ARGS_ENTRY(struct rte_flow_item_ppp, addr)),
+	},
+	[ITEM_PPP_CTRL] = {
+		.name = "ctrl",
+		.help = "ppp control",
+		.next = NEXT(item_ppp, NEXT_ENTRY(COMMON_UNSIGNED),
+			     item_param),
+		.args = ARGS(ARGS_ENTRY(struct rte_flow_item_ppp, ctrl)),
+	},
+	[ITEM_PPP_PROTO_ID] = {
+		.name = "proto_id",
+		.help = "ppp protocol id",
+		.next = NEXT(item_ppp, NEXT_ENTRY(COMMON_UNSIGNED),
+			     item_param),
+		.args = ARGS(ARGS_ENTRY(struct rte_flow_item_ppp, proto_id)),
+	},
 	/* Validate/create actions. */
 	[ACTIONS] = {
 		.name = "actions",
@@ -4125,6 +4346,24 @@ static const struct token token_list[] = {
 		.next = NEXT(NEXT_ENTRY(ACTION_NEXT)),
 		.call = parse_vc,
 	},
+	[ACTION_L2TPV2_ENCAP] = {
+		.name = "l2tpv2_encap",
+		.help = "L2TPV2 encapsulation, uses configuration set by \"set"
+			" l2tpv2\"",
+		.priv = PRIV_ACTION(L2TPV2_ENCAP,
+				    sizeof(struct action_l2tpv2_encap_data)),
+		.next = NEXT(NEXT_ENTRY(ACTION_NEXT)),
+		.call = parse_vc_action_l2tpv2_encap,
+	},
+	[ACTION_L2TPV2_DECAP] = {
+		.name = "l2tpv2_decap",
+		.help = "Performs a decapsulation action by stripping all"
+			" headers of the L2TPV2 tunnel network overlay from the"
+			" matched flow.",
+		.priv = PRIV_ACTION(L2TPV2_DECAP, 0),
+		.next = NEXT(NEXT_ENTRY(ACTION_NEXT)),
+		.call = parse_vc,
+	},
 	[ACTION_L2_ENCAP] = {
 		.name = "l2_encap",
 		.help = "l2 encap, uses configuration set by"
@@ -5907,6 +6146,152 @@ parse_vc_action_nvgre_encap(struct context *ctx, const struct token *token,
 	return ret;
 }
 
+/** Setup L2TPV2 encap configuration. */
+static int
+parse_setup_l2tpv2_encap_data(struct action_l2tpv2_encap_data *action_l2tpv2_encap_data)
+{
+	/* Set up default configuration. */
+	*action_l2tpv2_encap_data = (struct action_l2tpv2_encap_data){
+		.conf = (struct rte_flow_action_l2tpv2_encap){
+			.definition = action_l2tpv2_encap_data->items,
+		},
+		.items = {
+			{
+				.type = RTE_FLOW_ITEM_TYPE_ETH,
+				.spec = &action_l2tpv2_encap_data->item_eth,
+				.mask = &rte_flow_item_eth_mask,
+			},
+			{
+				.type = RTE_FLOW_ITEM_TYPE_VLAN,
+				.spec = &action_l2tpv2_encap_data->item_vlan,
+				.mask = &rte_flow_item_vlan_mask,
+			},
+			{
+				.type = RTE_FLOW_ITEM_TYPE_IPV4,
+				.spec = &action_l2tpv2_encap_data->item_ipv4,
+				.mask = &rte_flow_item_ipv4_mask,
+			},
+			{
+				.type = RTE_FLOW_ITEM_TYPE_UDP,
+				.spec = &action_l2tpv2_encap_data->item_udp,
+				.mask = &rte_flow_item_udp_mask,
+			},
+			{
+				.type = RTE_FLOW_ITEM_TYPE_L2TPV2,
+				.spec = &action_l2tpv2_encap_data->item_l2tpv2,
+				.mask = &rte_flow_item_l2tpv2_mask,
+			},
+			{
+				.type = RTE_FLOW_ITEM_TYPE_END,
+			},
+		},
+		.item_eth.type = 0,
+		.item_vlan = {
+			.tci = l2tpv2_encap_conf.vlan_tci,
+			.inner_type = 0,
+		},
+		.item_ipv4.hdr = {
+			.src_addr = l2tpv2_encap_conf.ipv4_src,
+			.dst_addr = l2tpv2_encap_conf.ipv4_dst,
+		},
+		.item_udp.hdr = {
+			.src_port = l2tpv2_encap_conf.udp_src,
+			.dst_port = l2tpv2_encap_conf.udp_dst,
+		},
+	};
+	memcpy(action_l2tpv2_encap_data->item_eth.dst.addr_bytes,
+	       l2tpv2_encap_conf.eth_dst, RTE_ETHER_ADDR_LEN);
+	memcpy(action_l2tpv2_encap_data->item_eth.src.addr_bytes,
+	       l2tpv2_encap_conf.eth_src, RTE_ETHER_ADDR_LEN);
+	if (!l2tpv2_encap_conf.select_ipv4) {
+		memcpy(&action_l2tpv2_encap_data->item_ipv6.hdr.src_addr,
+		       &l2tpv2_encap_conf.ipv6_src,
+		       sizeof(l2tpv2_encap_conf.ipv6_src));
+		memcpy(&action_l2tpv2_encap_data->item_ipv6.hdr.dst_addr,
+		       &l2tpv2_encap_conf.ipv6_dst,
+		       sizeof(l2tpv2_encap_conf.ipv6_dst));
+		action_l2tpv2_encap_data->items[2] = (struct rte_flow_item){
+			.type = RTE_FLOW_ITEM_TYPE_IPV6,
+			.spec = &action_l2tpv2_encap_data->item_ipv6,
+			.mask = &rte_flow_item_ipv6_mask,
+		};
+	}
+	if (!l2tpv2_encap_conf.select_vlan)
+		action_l2tpv2_encap_data->items[1].type =
+			RTE_FLOW_ITEM_TYPE_VOID;
+	if (l2tpv2_encap_conf.select_tos_ttl) {
+		if (l2tpv2_encap_conf.select_ipv4) {
+			static struct rte_flow_item_ipv4 ipv4_mask_tos;
+
+			memcpy(&ipv4_mask_tos, &rte_flow_item_ipv4_mask,
+			       sizeof(ipv4_mask_tos));
+			ipv4_mask_tos.hdr.type_of_service = 0xff;
+			ipv4_mask_tos.hdr.time_to_live = 0xff;
+			action_l2tpv2_encap_data->item_ipv4.hdr.type_of_service =
+					l2tpv2_encap_conf.ip_tos;
+			action_l2tpv2_encap_data->item_ipv4.hdr.time_to_live =
+					l2tpv2_encap_conf.ip_ttl;
+			action_l2tpv2_encap_data->items[2].mask =
+							&ipv4_mask_tos;
+		} else {
+			static struct rte_flow_item_ipv6 ipv6_mask_tos;
+
+			memcpy(&ipv6_mask_tos, &rte_flow_item_ipv6_mask,
+			       sizeof(ipv6_mask_tos));
+			ipv6_mask_tos.hdr.vtc_flow |=
+				RTE_BE32(0xfful << RTE_IPV6_HDR_TC_SHIFT);
+			ipv6_mask_tos.hdr.hop_limits = 0xff;
+			action_l2tpv2_encap_data->item_ipv6.hdr.vtc_flow |=
+				rte_cpu_to_be_32
+					((uint32_t)l2tpv2_encap_conf.ip_tos <<
+					 RTE_IPV6_HDR_TC_SHIFT);
+			action_l2tpv2_encap_data->item_ipv6.hdr.hop_limits =
+					l2tpv2_encap_conf.ip_ttl;
+			action_l2tpv2_encap_data->items[2].mask =
+							&ipv6_mask_tos;
+		}
+	}
+
+	if (0xc800 == (l2tpv2_encap_conf.flags_version & 0xcb00)) {
+		action_l2tpv2_encap_data->item_l2tpv2.hdr.type3.session_id =
+			l2tpv2_encap_conf.session_id;
+	} else if (0x4000 == (l2tpv2_encap_conf.flags_version & 0xcb00)) {
+		action_l2tpv2_encap_data->item_l2tpv2.hdr.type6.session_id =
+			l2tpv2_encap_conf.session_id;
+	}
+
+	return 0;
+}
+
+/** Parse l2tpv2 encap action. */
+static int
+parse_vc_action_l2tpv2_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_l2tpv2_encap_data *action_l2tpv2_encap_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;
+	action_l2tpv2_encap_data = ctx->object;
+	parse_setup_l2tpv2_encap_data(action_l2tpv2_encap_data);
+	action->conf = &action_l2tpv2_encap_data->conf;
+	return ret;
+}
+
 /** Parse l2 encap action. */
 static int
 parse_vc_action_l2_encap(struct context *ctx, const struct token *token,
@@ -8333,6 +8718,12 @@ flow_item_default_mask(const struct rte_flow_item *item)
 	case RTE_FLOW_ITEM_TYPE_PFCP:
 		mask = &rte_flow_item_pfcp_mask;
 		break;
+	case RTE_FLOW_ITEM_TYPE_L2TPV2:
+		mask = &rte_flow_item_l2tpv2_mask;
+		break;
+	case RTE_FLOW_ITEM_TYPE_PPP:
+		mask = &rte_flow_item_ppp_mask;
+		break;
 	default:
 		break;
 	}
@@ -8432,6 +8823,11 @@ cmd_set_raw_parsed_sample(const struct buffer *in)
 			parse_setup_nvgre_encap_data(&sample_nvgre_encap[idx]);
 			action->conf = &sample_nvgre_encap[idx];
 			break;
+		case RTE_FLOW_ACTION_TYPE_L2TPV2_ENCAP:
+			size = sizeof(struct rte_flow_action_l2tpv2_encap);
+			parse_setup_l2tpv2_encap_data(&sample_l2tpv2_encap[idx]);
+			action->conf = &sample_l2tpv2_encap[idx];
+			break;
 		default:
 			fprintf(stderr, "Error - Not supported action\n");
 			return;
diff --git a/app/test-pmd/testpmd.h b/app/test-pmd/testpmd.h
index e9d9db06ce..c744799b46 100644
--- a/app/test-pmd/testpmd.h
+++ b/app/test-pmd/testpmd.h
@@ -567,6 +567,28 @@ struct nvgre_encap_conf {
 
 extern struct nvgre_encap_conf nvgre_encap_conf;
 
+/* L2TPV2 encap/decap parameters. */
+struct l2tpv2_encap_conf {
+	uint32_t select_ipv4:1;
+	uint32_t select_vlan:1;
+	uint32_t select_tos_ttl:1;
+	rte_be16_t flags_version;
+	rte_be16_t session_id;
+	rte_be16_t udp_src;
+	rte_be16_t udp_dst;
+	rte_be32_t ipv4_src;
+	rte_be32_t ipv4_dst;
+	uint8_t ipv6_src[16];
+	uint8_t ipv6_dst[16];
+	rte_be16_t vlan_tci;
+	uint8_t ip_tos;
+	uint8_t ip_ttl;
+	uint8_t eth_src[RTE_ETHER_ADDR_LEN];
+	uint8_t eth_dst[RTE_ETHER_ADDR_LEN];
+};
+
+extern struct l2tpv2_encap_conf l2tpv2_encap_conf;
+
 /* L2 encap parameters. */
 struct l2_encap_conf {
 	uint32_t select_ipv4:1;
-- 
2.25.1


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

* Re: [dpdk-dev] [PATCH v3 1/3] ethdev: support PPP and L2TPV2 procotol
  2021-10-15  9:58     ` [dpdk-dev] [PATCH v3 1/3] ethdev: support PPP and L2TPV2 procotol Jie Wang
@ 2021-10-15 11:10       ` Ferruh Yigit
  2021-10-17  8:12         ` Ori Kam
  2021-10-17  8:19       ` Ori Kam
  1 sibling, 1 reply; 71+ messages in thread
From: Ferruh Yigit @ 2021-10-15 11:10 UTC (permalink / raw)
  To: Jie Wang, dev
  Cc: orika, thomas, andrew.rybchenko, xiaoyun.li, stevex.yang,
	jingjing.wu, beilei.xing, wenjun1.wu

On 10/15/2021 10:58 AM, Jie Wang wrote:
> +/**
> + * @warning
> + * @b EXPERIMENTAL: this structure may change without prior notice
> + * RTE_FLOW_ITEM_TYPE_PPP
> + *
> + * Matches PPP Header
> + */
> +struct rte_flow_item_ppp {
> +	uint8_t addr; /**< ppp address(8) */
> +	uint8_t ctrl; /**< ppp control(8) */
> +	rte_be16_t proto_id; /**< ppp protocol id(16) */
> +};

Hi Jie,

Can't we do same thing for ppp, have the protocol header in the lib/net
and use it within the 'rte_flow_item_ppp'?

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

* Re: [dpdk-dev] [PATCH v3 1/3] ethdev: support PPP and L2TPV2 procotol
  2021-10-15 11:10       ` Ferruh Yigit
@ 2021-10-17  8:12         ` Ori Kam
  0 siblings, 0 replies; 71+ messages in thread
From: Ori Kam @ 2021-10-17  8:12 UTC (permalink / raw)
  To: Ferruh Yigit, Jie Wang, dev
  Cc: NBU-Contact-Thomas Monjalon, andrew.rybchenko, xiaoyun.li,
	stevex.yang, jingjing.wu, beilei.xing, wenjun1.wu

HI Jie,

> -----Original Message-----
> From: Ferruh Yigit <ferruh.yigit@intel.com>
> Sent: Friday, October 15, 2021 2:10 PM
> Subject: Re: [PATCH v3 1/3] ethdev: support PPP and L2TPV2 procotol
> 
> On 10/15/2021 10:58 AM, Jie Wang wrote:
> > +/**
> > + * @warning
> > + * @b EXPERIMENTAL: this structure may change without prior notice
> > + * RTE_FLOW_ITEM_TYPE_PPP
> > + *
> > + * Matches PPP Header
> > + */
> > +struct rte_flow_item_ppp {
> > +	uint8_t addr; /**< ppp address(8) */
> > +	uint8_t ctrl; /**< ppp control(8) */
> > +	rte_be16_t proto_id; /**< ppp protocol id(16) */ };
> 
> Hi Jie,
> 
> Can't we do same thing for ppp, have the protocol header in the lib/net and use it within the
> 'rte_flow_item_ppp'?
+1
Ori

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

* Re: [dpdk-dev] [PATCH v3 1/3] ethdev: support PPP and L2TPV2 procotol
  2021-10-15  9:58     ` [dpdk-dev] [PATCH v3 1/3] ethdev: support PPP and L2TPV2 procotol Jie Wang
  2021-10-15 11:10       ` Ferruh Yigit
@ 2021-10-17  8:19       ` Ori Kam
  1 sibling, 0 replies; 71+ messages in thread
From: Ori Kam @ 2021-10-17  8:19 UTC (permalink / raw)
  To: Jie Wang, dev
  Cc: ferruh.yigit, NBU-Contact-Thomas Monjalon, andrew.rybchenko,
	xiaoyun.li, stevex.yang, jingjing.wu, beilei.xing, wenjun1.wu


Hi Jie,

> -----Original Message-----
> From: Jie Wang <jie1x.wang@intel.com>
> Sent: Friday, October 15, 2021 12:58 PM
> To: dev@dpdk.org
> Wang <jie1x.wang@intel.com>
> Subject: [PATCH v3 1/3] ethdev: support PPP and L2TPV2 procotol
> 
> Added flow pattern items and header formats of L2TPv2 and PPP to support PPP over L2TPv2 over
> UDP protocol RSS Hash.
> 

Like in the subject you are not talking about RSS you are talking about matching on items.

> Signed-off-by: Wenjun Wu <wenjun1.wu@intel.com>
> Signed-off-by: Jie Wang <jie1x.wang@intel.com>
> ---
>  doc/guides/prog_guide/rte_flow.rst     |  25 +++
>  doc/guides/rel_notes/release_21_11.rst |   5 +
>  lib/ethdev/rte_flow.c                  |   2 +
>  lib/ethdev/rte_flow.h                  | 117 ++++++++++++++
>  lib/net/rte_l2tpv2.h                   | 214 +++++++++++++++++++++++++
>  5 files changed, 363 insertions(+)
>  create mode 100644 lib/net/rte_l2tpv2.h
> 
> diff --git a/doc/guides/prog_guide/rte_flow.rst b/doc/guides/prog_guide/rte_flow.rst
> index 3cb014c1fa..59fe7e79b5 100644
> --- a/doc/guides/prog_guide/rte_flow.rst
> +++ b/doc/guides/prog_guide/rte_flow.rst
> @@ -1425,6 +1425,31 @@ Matches a conntrack state after conntrack action.
>  - ``flags``: conntrack packet state flags.
>  - Default ``mask`` matches all state bits.
> 
> +Item: ``L2TPV2``
> +^^^^^^^^^^^^^^^^^^^
> +
> +Matches a L2TPv2 header.
> +
> +- ``flags_version``: flags(12b), version(4b).
> +- ``length``: total length of the message.
> +- ``tunnel_id``: identifier for the control connection.
> +- ``session_id``: identifier for a session within a tunnel.
> +- ``ns``: sequence number for this date or control message.
> +- ``nr``: sequence number expected in the next control message to be received.
> +- ``offset_size``: offset of payload data.
> +- ``offset_padding``: offset padding, variable length.
> +- Default ``mask`` matches flags_version only.
> +
> +Item: ``PPP``
> +^^^^^^^^^^^^^^^^^^^
> +
> +Matches a PPP header.
> +
> +- ``addr``: ppp address.
> +- ``ctrl``: ppp control.
> +- ``proto_id``: ppp protocol identifier.
> +- Default ``mask`` matches addr, ctrl, proto_id.
> +
>  Actions
>  ~~~~~~~
> 
> diff --git a/doc/guides/rel_notes/release_21_11.rst b/doc/guides/rel_notes/release_21_11.rst
> index d5c762df62..503f6dd828 100644
> --- a/doc/guides/rel_notes/release_21_11.rst
> +++ b/doc/guides/rel_notes/release_21_11.rst
> @@ -81,6 +81,11 @@ New Features
>    * Default VLAN strip behavior was changed. VLAN tag won't be stripped
>      unless ``DEV_RX_OFFLOAD_VLAN_STRIP`` offload is enabled.
> 
> +* **Added L2TPV2 and PPP protocol support in rte_flow.**
> +
> +  Added flow pattern items and header formats of L2TPv2 and PPP to
> + support  PPP over L2TPv2 over UDP protocol RSS Hash.
> +
>  * **Updated AF_XDP PMD.**
> 
>    * Disabled secondary process support.
> diff --git a/lib/ethdev/rte_flow.c b/lib/ethdev/rte_flow.c index 8cb7a069c8..1ec739a031 100644
> --- a/lib/ethdev/rte_flow.c
> +++ b/lib/ethdev/rte_flow.c
> @@ -100,6 +100,8 @@ static const struct rte_flow_desc_data rte_flow_desc_item[] = {
>  	MK_FLOW_ITEM(GENEVE_OPT, sizeof(struct rte_flow_item_geneve_opt)),
>  	MK_FLOW_ITEM(INTEGRITY, sizeof(struct rte_flow_item_integrity)),
>  	MK_FLOW_ITEM(CONNTRACK, sizeof(uint32_t)),
> +	MK_FLOW_ITEM(L2TPV2, sizeof(struct rte_flow_item_l2tpv2)),
> +	MK_FLOW_ITEM(PPP, sizeof(struct rte_flow_item_ppp)),
>  };
> 
>  /** Generate flow_action[] entry. */
> diff --git a/lib/ethdev/rte_flow.h b/lib/ethdev/rte_flow.h index 5f87851f8c..f8fcf9c1f8 100644
> --- a/lib/ethdev/rte_flow.h
> +++ b/lib/ethdev/rte_flow.h
> @@ -35,6 +35,7 @@
>  #include <rte_mbuf_dyn.h>
>  #include <rte_meter.h>
>  #include <rte_gtp.h>
> +#include <rte_l2tpv2.h>
> 
>  #ifdef __cplusplus
>  extern "C" {
> @@ -574,6 +575,21 @@ enum rte_flow_item_type {
>  	 * @see struct rte_flow_item_conntrack.
>  	 */
>  	RTE_FLOW_ITEM_TYPE_CONNTRACK,
> +
> +	/**
> +	 * Matches L2TPV2 Header.
> +	 *
> +	 * See struct rte_flow_item_l2tpv2.
> +	 */
> +	RTE_FLOW_ITEM_TYPE_L2TPV2,
> +
> +	/**
> +	 * Matches PPP Header.
> +	 *
> +	 * See struct rte_flow_item_ppp.
> +	 */
> +	RTE_FLOW_ITEM_TYPE_PPP,
> +
>  };
> 
>  /**
> @@ -1799,6 +1815,55 @@ static const struct rte_flow_item_conntrack
> rte_flow_item_conntrack_mask = {  };  #endif
> 
> +/**
> + * @warning
> + * @b EXPERIMENTAL: this structure may change without prior notice
> + * RTE_FLOW_ITEM_TYPE_L2TPV2
> + *
> + * Matches L2TPv2 Header
> + */
> +struct rte_flow_item_l2tpv2 {
> +	struct rte_l2tpv2_combined_msg_hdr hdr; };
> +
> +/** Default mask for RTE_FLOW_ITEM_TYPE_L2TPV2. */ #ifndef __cplusplus
> +static const struct rte_flow_item_l2tpv2 rte_flow_item_l2tpv2_mask = {
> +	/*
> +	 * flags and version bit mask
> +	 * 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0
> +	 * T L x x S x O P x x x x V V V V
> +	 */
> +	.hdr = {
> +		.common = {
> +			.flags_version = 0xcb0f,
> +		},
> +	},
> +};
> +#endif
> +
> +/**
> + * @warning
> + * @b EXPERIMENTAL: this structure may change without prior notice
> + * RTE_FLOW_ITEM_TYPE_PPP
> + *
> + * Matches PPP Header
> + */
> +struct rte_flow_item_ppp {
> +	uint8_t addr; /**< ppp address(8) */
> +	uint8_t ctrl; /**< ppp control(8) */
> +	rte_be16_t proto_id; /**< ppp protocol id(16) */ };
> +
> +/** Default mask for RTE_FLOW_ITEM_TYPE_PPP. */ #ifndef __cplusplus
> +static const struct rte_flow_item_ppp rte_flow_item_ppp_mask = {
> +	.addr = 0xff,
> +	.ctrl = 0xff,
> +	.proto_id = 0xffff,
> +};
> +#endif
> +
>  /**
>   * Matching pattern item definition.
>   *
> @@ -2417,6 +2482,23 @@ enum rte_flow_action_type {
>  	 * See struct rte_flow_action_meter_color.
>  	 */
>  	RTE_FLOW_ACTION_TYPE_METER_COLOR,
> +
> +	/**
> +	 * Encapsulate flow in L2TPV2 tunnel defined in the
> +	 * rte_flow_action_l2tpv2_encap action structure.
> +	 *
> +	 * See struct rte_flow_action_l2tpv2_encap.
> +	 */
> +	RTE_FLOW_ACTION_TYPE_L2TPV2_ENCAP,

Does action are not needed, to encap you have the raw encap.
My comment about the encap was in the testpmd patch. Where you should see
that when you are trying to encap using the raw command it works correctly.

This comment is for all encap/decap additions in this patch.

> +
> +	/**
> +	 * Decapsulate outer most L2TPV2 tunnel from matched flow.
> +	 *
> +	 * If flow pattern does not define a valid L2TPV2 tunnel (as specified
> +	 * by RFC2661) then the PMD should return a RTE_FLOW_ERROR_TYPE_ACTION
> +	 * error.
> +	 */
> +	RTE_FLOW_ACTION_TYPE_L2TPV2_DECAP,

See comment above.

>  };
> 
>  /**
> @@ -3162,6 +3244,41 @@ struct rte_flow_action_meter_color {
>  	enum rte_color color; /**< Packet color. */  };
> 
> +/**
> + * @warning
> + * @b EXPERIMENTAL: this structure may change without prior notice
> + *
> + * RTE_FLOW_ACTION_TYPE_L2TPV2_ENCAP
> + *
> + * L2TPV2 tunnel end-point encapsulation data definition
> + *
> + * The tunnel definition is provided through the flow item pattern  the
> + * provided pattern must conform with RFC7637. The flow definition must
> +be
> + * provided in order from the RTE_FLOW_ITEM_TYPE_ETH definition up the
> +end item
> + * which is specified by RTE_FLOW_ITEM_TYPE_END.
> + *
> + * The mask field allows user to specify which fields in the flow item
> + * definitions can be ignored and which have valid data and can be used
> + * verbatim.
> + *
> + * Note: the last field is not used in the definition of a tunnel and
> +can be
> + * ignored.
> + *
> + * Valid flow definition for RTE_FLOW_ACTION_TYPE_L2TPV2_ENCAP include:
> + *
> + * - ETH / IPV4 / UDP / L2TPV2 / END
> + * - ETH / IPV6 / UDP / L2TPV2 / END
> + * - ETH / VLAN / IPV4 / UDP / L2TPV2 / END
> + *
> + */
> +struct rte_flow_action_l2tpv2_encap {
> +	/**
> +	 * Encapsulating l2tpv2 tunnel definition
> +	 * (terminated by the END pattern item).
> +	 */
> +	struct rte_flow_item *definition;
> +};
> +
>  /**
>   * Field IDs for MODIFY_FIELD action.
>   */
> diff --git a/lib/net/rte_l2tpv2.h b/lib/net/rte_l2tpv2.h new file mode 100644 index
> 0000000000..aea3c689be
> --- /dev/null
> +++ b/lib/net/rte_l2tpv2.h
> @@ -0,0 +1,214 @@
> +/* SPDX-License-Identifier: BSD-3-Clause
> + * Copyright 2021 Mellanox Technologies, Ltd  */
> +
> +#ifndef _RTE_L2TPV2_H_
> +#define _RTE_L2TPV2_H_
> +
> +/**
> + * @file
> + *
> + * L2TP header:
> + *  0                   1                   2                   3
> + *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
> + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
> + * |T|L|x|x|S|x|O|P|x|x|x|x|  Ver  |          Length (opt)         |
> + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
> + * |           Tunnel ID           |           Session ID          |
> + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
> + * |             Ns (opt)          |             Nr (opt)          |
> + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
> + * |      Offset Size (opt)        |    Offset pad... (opt)
> + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
> + *
> + * The Type (T) bit indicates the type of message. It is set to 0 for a
> +data
> + * message and 1 for a control message.
> + *
> + * If the Length (L) bit is 1, the Length field is present. This bit
> +MUST be
> + * set to 1 for control messages.
> + *
> + * The x bits are reserved for future extensions. All reserved bits
> +MUST
> + * be set to 0 on outgoing messages and ignored on incoming messages.
> + *
> + * If the Sequence (S) bit is set to 1 the Ns and Nr fields are present.
> + * The S bit MUST be set to 1 for control messages.
> + *
> + * If the Offset (O) bit is 1, the Offset Size field is present. The O
> + * bit MUST be set to 0 for control messages.
> + *
> + * If the Priority (P) bit is 1, this data message should receive
> + * preferential treatment in its local queuing and transmission.
> + * The P bit MUST be set to 0 for control messages.
> + *
> + * Ver MUST be 2, indicating the version of the L2TP data message header.
> + *
> + * The Length field indicates the total length of the message in octets.
> + *
> + * Tunnel ID indicates the identifier for the control connection.
> + *
> + * Session ID indicates the identifier for a session within a tunnel.
> + *
> + * Ns indicates the sequence number for this data or control message.
> + *
> + * Nr indicates the sequence number expected in the next control
> +message
> + * to be received.
> + *
> + * The Offset Size field, if present, specifies the number of octets
> + * past the L2TP header at which the payload data is expected to start.
> + * Actual data within the offset padding is undefined. If the offset
> + * field is present, the L2TP header ends after the last octet of the
> + * offset padding.
> + */
> +
> +#include <stdint.h>
> +#include <rte_byteorder.h>
> +
> +#ifdef __cplusplus
> +extern "C" {
> +#endif
> +
> +/**
> + * L2TPv2 Common Header
> + */
> +RTE_STD_C11
> +struct rte_l2tpv2_common_hdr {
> +	union {
> +		rte_be16_t flags_version;
> +		struct {
> +#if RTE_BYTE_ORDER == RTE_LITTLE_ENDIAN
> +			rte_be16_t t:1;		/**< message Type */
> +			rte_be16_t l:1;		/**< length option bit*/
> +			rte_be16_t res1:2;	/**< reserved */
> +			rte_be16_t s:1;		/**< ns/nr option bit*/
> +			rte_be16_t res2:1;	/**< reserved */
> +			rte_be16_t o:1;		/**< offset option bit*/
> +			rte_be16_t p:1;		/**< priority option bit*/
> +			rte_be16_t res3:4;	/**< reserved */
> +			rte_be16_t ver:4;	/**< protocol version */
> +#elif RTE_BYTE_ORDER == RTE_BIG_ENDIAN
> +			rte_be16_t ver:4;	/**< protocol version */
> +			rte_be16_t res3:4;	/**< reserved */
> +			rte_be16_t p:1;		/**< priority option bit*/
> +			rte_be16_t o:1;		/**< offset option bit*/
> +			rte_be16_t res2:1;	/**< reserved */
> +			rte_be16_t s:1;		/**< ns/nr option bit*/
> +			rte_be16_t res1:2;	/**< reserved */
> +			rte_be16_t l:1;		/**< length option bit*/
> +			rte_be16_t t:1;		/**< message Type */
> +#endif
> +		};
> +	};
> +};
> +
> +/*
> + * L2TPv2 message Header contains all options(length, ns, nr,
> + * offset size, offset padding).
> + */
> +struct rte_l2tpv2_msg_with_all_options {
> +	rte_be16_t length;		/**< length(16) */
> +	rte_be16_t tunnel_id;		/**< tunnel id(16) */
> +	rte_be16_t session_id;		/**< session id(16) */
> +	rte_be16_t ns;			/**< Ns(16) */
> +	rte_be16_t nr;			/**< Nr(16) */
> +	rte_be16_t offset_size;		/**< offset size(16) */
> +	uint8_t   *offset_padding;	/**< offset padding(variable length) */
> +};
> +
> +/*
> + * L2TPv2 message Header contains all options except length(ns, nr,
> + * offset size, offset padding).
> + */
> +struct rte_l2tpv2_msg_without_length {
> +	rte_be16_t tunnel_id;		/**< tunnel id(16) */
> +	rte_be16_t session_id;		/**< session id(16) */
> +	rte_be16_t ns;			/**< Ns(16) */
> +	rte_be16_t nr;			/**< Nr(16) */
> +	rte_be16_t offset_size;		/**< offset size(16) */
> +	uint8_t   *offset_padding;	/**< offset padding(variable length) */
> +};
> +
> +/*
> + * L2TPv2 message Header contains all options except ns_nr(length,
> + * offset size, offset padding).
> + * Ns and Nr MUST be toghter.
> + */
> +struct rte_l2tpv2_msg_without_ns_nr {
> +	rte_be16_t length;		/**< length(16) */
> +	rte_be16_t tunnel_id;		/**< tunnel id(16) */
> +	rte_be16_t session_id;		/**< session id(16) */
> +	rte_be16_t offset_size;		/**< offset size(16) */
> +	uint8_t   *offset_padding;	/**< offset padding(variable length) */
> +};
> +
> +/*
> + * L2TPv2 message Header contains all options except ns_nr(length, ns, nr).
> + * offset size and offset padding MUST be toghter.
> + */
> +struct rte_l2tpv2_msg_without_offset {
> +	rte_be16_t length;		/**< length(16) */
> +	rte_be16_t tunnel_id;		/**< tunnel id(16) */
> +	rte_be16_t session_id;		/**< session id(16) */
> +	rte_be16_t ns;			/**< Ns(16) */
> +	rte_be16_t nr;			/**< Nr(16) */
> +};
> +
> +/*
> + * L2TPv2 message Header contains options offset size and offset padding.
> + */
> +struct rte_l2tpv2_msg_with_offset {
> +	rte_be16_t tunnel_id;		/**< tunnel id(16) */
> +	rte_be16_t session_id;		/**< session id(16) */
> +	rte_be16_t offset_size;		/**< offset size(16) */
> +	uint8_t   *offset_padding;	/**< offset padding(variable length) */
> +};
> +
> +/*
> + * L2TPv2 message Header contains options ns and nr.
> + */
> +struct rte_l2tpv2_msg_with_ns_nr {
> +	rte_be16_t tunnel_id;		/**< tunnel id(16) */
> +	rte_be16_t session_id;		/**< session id(16) */
> +	rte_be16_t ns;			/**< Ns(16) */
> +	rte_be16_t nr;			/**< Nr(16) */
> +};
> +
> +/*
> + * L2TPv2 message Header contains option length.
> + */
> +struct rte_l2tpv2_msg_with_length {
> +	rte_be16_t length;		/**< length(16) */
> +	rte_be16_t tunnel_id;		/**< tunnel id(16) */
> +	rte_be16_t session_id;		/**< session id(16) */
> +};
> +
> +/*
> + * L2TPv2 message Header without all options.
> + */
> +struct rte_l2tpv2_msg_without_all_options {
> +	rte_be16_t tunnel_id;		/**< tunnel id(16) */
> +	rte_be16_t session_id;		/**< session id(16) */
> +};
> +
> +/**
> + * L2TPv2 Combined Message Header Format: Common Header + Options  */
> +RTE_STD_C11
> +struct rte_l2tpv2_combined_msg_hdr {
> +	struct rte_l2tpv2_common_hdr common;
> +	union {
> +		struct rte_l2tpv2_msg_with_all_options type0;
> +		struct rte_l2tpv2_msg_without_length type1;
> +		struct rte_l2tpv2_msg_without_ns_nr type2;
> +		struct rte_l2tpv2_msg_without_offset type3;
> +		struct rte_l2tpv2_msg_with_offset type4;
> +		struct rte_l2tpv2_msg_with_ns_nr type5;
> +		struct rte_l2tpv2_msg_with_length type6;
> +		struct rte_l2tpv2_msg_without_all_options type7;
> +	};
> +};
> +
> +#ifdef __cplusplus
> +}
> +#endif
> +
> +#endif /* _RTE_L2TPV2_H_ */
> --
> 2.25.1

Best,
Ori

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

* Re: [dpdk-dev] [PATCH v3 3/3] app/testpmd: support L2TPV2 and PPP protocol pattern
  2021-10-15  9:58     ` [dpdk-dev] [PATCH v3 3/3] app/testpmd: support L2TPV2 and PPP protocol pattern Jie Wang
@ 2021-10-17  8:51       ` Ori Kam
  0 siblings, 0 replies; 71+ messages in thread
From: Ori Kam @ 2021-10-17  8:51 UTC (permalink / raw)
  To: Jie Wang, dev
  Cc: ferruh.yigit, NBU-Contact-Thomas Monjalon, andrew.rybchenko,
	xiaoyun.li, stevex.yang, jingjing.wu, beilei.xing, wenjun1.wu

Hi Jie,

Sorry if I wan't clear on my last review.

You don't need to implement encap/decap for those protocols just make sure they are working
with the set encap and set decap along with the raw action.

You can look at cmd_set_raw_parsed and use other tunnels as reference (for example gtp).


> -----Original Message-----
> From: Jie Wang <jie1x.wang@intel.com>
> Sent: Friday, October 15, 2021 12:58 PM
> To: dev@dpdk.org
> Subject: [PATCH v3 3/3] app/testpmd: support L2TPV2 and PPP protocol pattern
> 
> Add support for test-pmd to parse protocol pattern L2TPv2 and PPP.
> 
> Signed-off-by: Wenjun Wu <wenjun1.wu@intel.com>
> Signed-off-by: Jie Wang <jie1x.wang@intel.com>
> ---
>  app/test-pmd/cmdline.c      | 244 ++++++++++++++++++++++
>  app/test-pmd/cmdline_flow.c | 396 ++++++++++++++++++++++++++++++++++++
>  app/test-pmd/testpmd.h      |  22 ++
>  3 files changed, 662 insertions(+)
> 
> diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c index 36d50fd3c7..bba761ad4b 100644
> --- a/app/test-pmd/cmdline.c
> +++ b/app/test-pmd/cmdline.c
> @@ -13300,6 +13300,247 @@ cmdline_parse_inst_t cmd_set_nvgre_with_vlan = {
>  	},
>  };
> 
> +/** Set L2TPV2 encapsulation details */ struct cmd_set_l2tpv2_result {
> +	cmdline_fixed_string_t set;
> +	cmdline_fixed_string_t l2tpv2;
> +	cmdline_fixed_string_t pos_token;
> +	cmdline_fixed_string_t ip_version;
> +	uint32_t vlan_present:1;
> +	uint16_t flags_version;
> +	uint16_t session_id;
> +	uint16_t udp_src;
> +	uint16_t udp_dst;
> +	cmdline_ipaddr_t ip_src;
> +	cmdline_ipaddr_t ip_dst;
> +	uint16_t tci;
> +	uint8_t tos;
> +	uint8_t ttl;
> +	struct rte_ether_addr eth_src;
> +	struct rte_ether_addr eth_dst;
> +};
> +
> +cmdline_parse_token_string_t cmd_set_l2tpv2_set =
> +	TOKEN_STRING_INITIALIZER(struct cmd_set_l2tpv2_result, set, "set");
> +cmdline_parse_token_string_t cmd_set_l2tpv2_l2tpv2 =
> +	TOKEN_STRING_INITIALIZER(struct cmd_set_l2tpv2_result, l2tpv2,
> +"l2tpv2"); cmdline_parse_token_string_t cmd_set_l2tpv2_l2tpv2_tos_ttl =
> +	TOKEN_STRING_INITIALIZER(struct cmd_set_l2tpv2_result, l2tpv2,
> +				 "l2tpv2-tos-ttl");
> +cmdline_parse_token_string_t cmd_set_l2tpv2_l2tpv2_with_vlan =
> +	TOKEN_STRING_INITIALIZER(struct cmd_set_l2tpv2_result, l2tpv2,
> +				 "l2tpv2-with-vlan");
> +cmdline_parse_token_string_t cmd_set_l2tpv2_ip_version =
> +	TOKEN_STRING_INITIALIZER(struct cmd_set_l2tpv2_result, pos_token,
> +				 "ip-version");
> +cmdline_parse_token_string_t cmd_set_l2tpv2_ip_version_value =
> +	TOKEN_STRING_INITIALIZER(struct cmd_set_l2tpv2_result, ip_version,
> +				 "ipv4#ipv6");
> +cmdline_parse_token_string_t cmd_set_l2tpv2_flags_version =
> +	TOKEN_STRING_INITIALIZER(struct cmd_set_l2tpv2_result, pos_token,
> +				 "flags_version");
> +cmdline_parse_token_num_t cmd_set_l2tpv2_flags_version_value =
> +	TOKEN_NUM_INITIALIZER(struct cmd_set_l2tpv2_result, flags_version,
> +			      RTE_UINT16);
> +cmdline_parse_token_string_t cmd_set_l2tpv2_session_id =
> +	TOKEN_STRING_INITIALIZER(struct cmd_set_l2tpv2_result, pos_token,
> +				 "session_id");
> +cmdline_parse_token_num_t cmd_set_l2tpv2_session_id_value =
> +	TOKEN_NUM_INITIALIZER(struct cmd_set_l2tpv2_result, session_id,
> +			      RTE_UINT16);
> +cmdline_parse_token_string_t cmd_set_l2tpv2_udp_src =
> +	TOKEN_STRING_INITIALIZER(struct cmd_set_l2tpv2_result, pos_token,
> +				 "udp-src");
> +cmdline_parse_token_num_t cmd_set_l2tpv2_udp_src_value =
> +	TOKEN_NUM_INITIALIZER(struct cmd_set_l2tpv2_result, udp_src,
> +			      RTE_UINT16);
> +cmdline_parse_token_string_t cmd_set_l2tpv2_udp_dst =
> +	TOKEN_STRING_INITIALIZER(struct cmd_set_l2tpv2_result, pos_token,
> +				 "udp-dst");
> +cmdline_parse_token_num_t cmd_set_l2tpv2_udp_dst_value =
> +	TOKEN_NUM_INITIALIZER(struct cmd_set_l2tpv2_result, udp_dst,
> +			      RTE_UINT16);
> +cmdline_parse_token_string_t cmd_set_l2tpv2_ip_tos =
> +	TOKEN_STRING_INITIALIZER(struct cmd_set_l2tpv2_result, pos_token,
> +				 "ip-tos");
> +cmdline_parse_token_num_t cmd_set_l2tpv2_ip_tos_value =
> +	TOKEN_NUM_INITIALIZER(struct cmd_set_l2tpv2_result, tos, RTE_UINT8);
> +cmdline_parse_token_string_t cmd_set_l2tpv2_ip_ttl =
> +	TOKEN_STRING_INITIALIZER(struct cmd_set_l2tpv2_result, pos_token,
> +				 "ip-ttl");
> +cmdline_parse_token_num_t cmd_set_l2tpv2_ip_ttl_value =
> +	TOKEN_NUM_INITIALIZER(struct cmd_set_l2tpv2_result, ttl, RTE_UINT8);
> +cmdline_parse_token_string_t cmd_set_l2tpv2_ip_src =
> +	TOKEN_STRING_INITIALIZER(struct cmd_set_l2tpv2_result, pos_token,
> +				 "ip-src");
> +cmdline_parse_token_ipaddr_t cmd_set_l2tpv2_ip_src_value =
> +	TOKEN_IPADDR_INITIALIZER(struct cmd_set_l2tpv2_result, ip_src);
> +cmdline_parse_token_string_t cmd_set_l2tpv2_ip_dst =
> +	TOKEN_STRING_INITIALIZER(struct cmd_set_l2tpv2_result, pos_token,
> +				 "ip-dst");
> +cmdline_parse_token_ipaddr_t cmd_set_l2tpv2_ip_dst_value =
> +	TOKEN_IPADDR_INITIALIZER(struct cmd_set_l2tpv2_result, ip_dst);
> +cmdline_parse_token_string_t cmd_set_l2tpv2_vlan =
> +	TOKEN_STRING_INITIALIZER(struct cmd_set_l2tpv2_result, pos_token,
> +				 "vlan-tci");
> +cmdline_parse_token_num_t cmd_set_l2tpv2_vlan_value =
> +	TOKEN_NUM_INITIALIZER(struct cmd_set_l2tpv2_result, tci, RTE_UINT16);
> +cmdline_parse_token_string_t cmd_set_l2tpv2_eth_src =
> +	TOKEN_STRING_INITIALIZER(struct cmd_set_l2tpv2_result, pos_token,
> +				 "eth-src");
> +cmdline_parse_token_etheraddr_t cmd_set_l2tpv2_eth_src_value =
> +	TOKEN_ETHERADDR_INITIALIZER(struct cmd_set_l2tpv2_result, eth_src);
> +cmdline_parse_token_string_t cmd_set_l2tpv2_eth_dst =
> +	TOKEN_STRING_INITIALIZER(struct cmd_set_l2tpv2_result, pos_token,
> +				 "eth-dst");
> +cmdline_parse_token_etheraddr_t cmd_set_l2tpv2_eth_dst_value =
> +	TOKEN_ETHERADDR_INITIALIZER(struct cmd_set_l2tpv2_result, eth_dst);
> +
> +static void cmd_set_l2tpv2_parsed(void *parsed_result,
> +	__rte_unused struct cmdline *cl,
> +	__rte_unused void *data)
> +{
> +	struct cmd_set_l2tpv2_result *res = parsed_result;
> +
> +	l2tpv2_encap_conf.select_tos_ttl = 0;
> +	if (strcmp(res->l2tpv2, "l2tpv2") == 0)
> +		l2tpv2_encap_conf.select_vlan = 0;
> +	else if (strcmp(res->l2tpv2, "l2tpv2-with-vlan") == 0)
> +		l2tpv2_encap_conf.select_vlan = 1;
> +	else if (strcmp(res->l2tpv2, "l2tpv2-tos-ttl") == 0) {
> +		l2tpv2_encap_conf.select_vlan = 0;
> +		l2tpv2_encap_conf.select_tos_ttl = 1;
> +	}
> +	if (strcmp(res->ip_version, "ipv4") == 0)
> +		l2tpv2_encap_conf.select_ipv4 = 1;
> +	else if (strcmp(res->ip_version, "ipv6") == 0)
> +		l2tpv2_encap_conf.select_ipv4 = 0;
> +	else
> +		return;
> +
> +	l2tpv2_encap_conf.flags_version = res->flags_version;
> +	l2tpv2_encap_conf.session_id = res->session_id;
> +	l2tpv2_encap_conf.udp_src = res->udp_src;
> +	l2tpv2_encap_conf.udp_dst = res->udp_dst;
> +	l2tpv2_encap_conf.ip_tos = res->tos;
> +	l2tpv2_encap_conf.ip_ttl = res->ttl;
> +	if (l2tpv2_encap_conf.select_ipv4) {
> +		IPV4_ADDR_TO_UINT(res->ip_src, l2tpv2_encap_conf.ipv4_src);
> +		IPV4_ADDR_TO_UINT(res->ip_dst, l2tpv2_encap_conf.ipv4_dst);
> +	} else {
> +		IPV6_ADDR_TO_ARRAY(res->ip_src, l2tpv2_encap_conf.ipv6_src);
> +		IPV6_ADDR_TO_ARRAY(res->ip_dst, l2tpv2_encap_conf.ipv6_dst);
> +	}
> +	if (l2tpv2_encap_conf.select_vlan)
> +		l2tpv2_encap_conf.vlan_tci = rte_cpu_to_be_16(res->tci);
> +	rte_memcpy(l2tpv2_encap_conf.eth_src, res->eth_src.addr_bytes,
> +		   RTE_ETHER_ADDR_LEN);
> +	rte_memcpy(l2tpv2_encap_conf.eth_dst, res->eth_dst.addr_bytes,
> +		   RTE_ETHER_ADDR_LEN);
> +}
> +
> +cmdline_parse_inst_t cmd_set_l2tpv2 = {
> +	.f = cmd_set_l2tpv2_parsed,
> +	.data = NULL,
> +	.help_str = "set l2tpv2 ip-version ipv4|ipv6 flags_version"
> +		" <flags_version> session_id <session_id> udp-src <udp-src>"
> +		" udp-dst <udp-dst> ip-src <ip-src> ip-dst <ip-dst> eth-src"
> +		" <eth-src> eth-dst <eth-dst>",
> +	.tokens = {
> +		(void *)&cmd_set_l2tpv2_set,
> +		(void *)&cmd_set_l2tpv2_l2tpv2,
> +		(void *)&cmd_set_l2tpv2_ip_version,
> +		(void *)&cmd_set_l2tpv2_ip_version_value,
> +		(void *)&cmd_set_l2tpv2_flags_version,
> +		(void *)&cmd_set_l2tpv2_flags_version_value,
> +		(void *)&cmd_set_l2tpv2_session_id,
> +		(void *)&cmd_set_l2tpv2_session_id_value,
> +		(void *)&cmd_set_l2tpv2_udp_src,
> +		(void *)&cmd_set_l2tpv2_udp_src_value,
> +		(void *)&cmd_set_l2tpv2_udp_dst,
> +		(void *)&cmd_set_l2tpv2_udp_dst_value,
> +		(void *)&cmd_set_l2tpv2_ip_src,
> +		(void *)&cmd_set_l2tpv2_ip_src_value,
> +		(void *)&cmd_set_l2tpv2_ip_dst,
> +		(void *)&cmd_set_l2tpv2_ip_dst_value,
> +		(void *)&cmd_set_l2tpv2_eth_src,
> +		(void *)&cmd_set_l2tpv2_eth_src_value,
> +		(void *)&cmd_set_l2tpv2_eth_dst,
> +		(void *)&cmd_set_l2tpv2_eth_dst_value,
> +		NULL,
> +	},
> +};
> +
> +cmdline_parse_inst_t cmd_set_l2tpv2_tos_ttl = {
> +	.f = cmd_set_l2tpv2_parsed,
> +	.data = NULL,
> +	.help_str = "set l2tpv2-tos-ttl ip-version ipv4|ipv6 flags_version"
> +		" <flags_version> session_id <session_id> udp-src <udp-src>"
> +		" udp-dst <udp-dst> ip-tos <ip-tos> ip-ttl <ip-ttl> ip-src"
> +		" <ip-src> ip-dst <ip-dst> eth-src <eth-src> eth-dst <eth-dst>",
> +	.tokens = {
> +		(void *)&cmd_set_l2tpv2_set,
> +		(void *)&cmd_set_l2tpv2_l2tpv2_tos_ttl,
> +		(void *)&cmd_set_l2tpv2_ip_version,
> +		(void *)&cmd_set_l2tpv2_ip_version_value,
> +		(void *)&cmd_set_l2tpv2_flags_version,
> +		(void *)&cmd_set_l2tpv2_flags_version_value,
> +		(void *)&cmd_set_l2tpv2_session_id,
> +		(void *)&cmd_set_l2tpv2_session_id_value,
> +		(void *)&cmd_set_l2tpv2_udp_src,
> +		(void *)&cmd_set_l2tpv2_udp_src_value,
> +		(void *)&cmd_set_l2tpv2_udp_dst,
> +		(void *)&cmd_set_l2tpv2_udp_dst_value,
> +		(void *)&cmd_set_l2tpv2_ip_tos,
> +		(void *)&cmd_set_l2tpv2_ip_tos_value,
> +		(void *)&cmd_set_l2tpv2_ip_ttl,
> +		(void *)&cmd_set_l2tpv2_ip_ttl_value,
> +		(void *)&cmd_set_l2tpv2_ip_src,
> +		(void *)&cmd_set_l2tpv2_ip_src_value,
> +		(void *)&cmd_set_l2tpv2_ip_dst,
> +		(void *)&cmd_set_l2tpv2_ip_dst_value,
> +		(void *)&cmd_set_l2tpv2_eth_src,
> +		(void *)&cmd_set_l2tpv2_eth_src_value,
> +		(void *)&cmd_set_l2tpv2_eth_dst,
> +		(void *)&cmd_set_l2tpv2_eth_dst_value,
> +		NULL,
> +	},
> +};
> +
> +cmdline_parse_inst_t cmd_set_l2tpv2_with_vlan = {
> +	.f = cmd_set_l2tpv2_parsed,
> +	.data = NULL,
> +	.help_str = "set l2tpv2-with-vlan ip-version ipv4|ipv6 flags_version"
> +		" <flags_version> session_id <session_id> udp-src <udp-src>"
> +		" udp-dst <udp-dst> ip-src <ip-src> ip-dst <ip-dst> vlan-tci"
> +		" <vlan-tci> eth-src <eth-src> eth-dst <eth-dst>",
> +	.tokens = {
> +		(void *)&cmd_set_l2tpv2_set,
> +		(void *)&cmd_set_l2tpv2_l2tpv2_with_vlan,
> +		(void *)&cmd_set_l2tpv2_ip_version,
> +		(void *)&cmd_set_l2tpv2_ip_version_value,
> +		(void *)&cmd_set_l2tpv2_flags_version,
> +		(void *)&cmd_set_l2tpv2_flags_version_value,
> +		(void *)&cmd_set_l2tpv2_session_id,
> +		(void *)&cmd_set_l2tpv2_session_id_value,
> +		(void *)&cmd_set_l2tpv2_udp_src,
> +		(void *)&cmd_set_l2tpv2_udp_src_value,
> +		(void *)&cmd_set_l2tpv2_udp_dst,
> +		(void *)&cmd_set_l2tpv2_udp_dst_value,
> +		(void *)&cmd_set_l2tpv2_ip_src,
> +		(void *)&cmd_set_l2tpv2_ip_src_value,
> +		(void *)&cmd_set_l2tpv2_ip_dst,
> +		(void *)&cmd_set_l2tpv2_ip_dst_value,
> +		(void *)&cmd_set_l2tpv2_vlan,
> +		(void *)&cmd_set_l2tpv2_vlan_value,
> +		(void *)&cmd_set_l2tpv2_eth_src,
> +		(void *)&cmd_set_l2tpv2_eth_src_value,
> +		(void *)&cmd_set_l2tpv2_eth_dst,
> +		(void *)&cmd_set_l2tpv2_eth_dst_value,
> +		NULL,
> +	},
> +};
> +
>  /** Set L2 encapsulation details */
>  struct cmd_set_l2_encap_result {
>  	cmdline_fixed_string_t set;
> @@ -17774,6 +18015,9 @@ cmdline_parse_ctx_t main_ctx[] = {
>  	(cmdline_parse_inst_t *)&cmd_set_vxlan_with_vlan,
>  	(cmdline_parse_inst_t *)&cmd_set_nvgre,
>  	(cmdline_parse_inst_t *)&cmd_set_nvgre_with_vlan,
> +	(cmdline_parse_inst_t *)&cmd_set_l2tpv2,
> +	(cmdline_parse_inst_t *)&cmd_set_l2tpv2_tos_ttl,
> +	(cmdline_parse_inst_t *)&cmd_set_l2tpv2_with_vlan,
>  	(cmdline_parse_inst_t *)&cmd_set_l2_encap,
>  	(cmdline_parse_inst_t *)&cmd_set_l2_encap_with_vlan,
>  	(cmdline_parse_inst_t *)&cmd_set_l2_decap, diff --git a/app/test-pmd/cmdline_flow.c
> b/app/test-pmd/cmdline_flow.c index 0b5856c7d5..4f73d4f39d 100644
> --- a/app/test-pmd/cmdline_flow.c
> +++ b/app/test-pmd/cmdline_flow.c
> @@ -306,6 +306,23 @@ enum index {
>  	ITEM_POL_PORT,
>  	ITEM_POL_METER,
>  	ITEM_POL_POLICY,
> +	ITEM_L2TPV2,
> +	ITEM_L2TPV2_COMMON,
> +	ITEM_L2TPV2_COMMON_TYPE,
> +	ITEM_L2TPV2_COMMON_TYPE_DATA_L,
> +	ITEM_L2TPV2_COMMON_TYPE_CTRL,
> +	ITEM_L2TPV2_MSG_DATA_L_LENGTH,
> +	ITEM_L2TPV2_MSG_DATA_L_TUNNEL_ID,
> +	ITEM_L2TPV2_MSG_DATA_L_SESSION_ID,
> +	ITEM_L2TPV2_MSG_CTRL_LENGTH,
> +	ITEM_L2TPV2_MSG_CTRL_TUNNEL_ID,
> +	ITEM_L2TPV2_MSG_CTRL_SESSION_ID,
> +	ITEM_L2TPV2_MSG_CTRL_NS,
> +	ITEM_L2TPV2_MSG_CTRL_NR,
> +	ITEM_PPP,
> +	ITEM_PPP_ADDR,
> +	ITEM_PPP_CTRL,
> +	ITEM_PPP_PROTO_ID,
> 
>  	/* Validate/create actions. */
>  	ACTIONS,
> @@ -376,6 +393,8 @@ enum index {
>  	ACTION_VXLAN_DECAP,
>  	ACTION_NVGRE_ENCAP,
>  	ACTION_NVGRE_DECAP,
> +	ACTION_L2TPV2_ENCAP,
> +	ACTION_L2TPV2_DECAP,
>  	ACTION_L2_ENCAP,
>  	ACTION_L2_DECAP,
>  	ACTION_MPLSOGRE_ENCAP,
> @@ -581,6 +600,44 @@ struct action_nvgre_encap_data {
>  	struct rte_flow_item_nvgre item_nvgre;  };
> 
> +struct l2tpv2_encap_conf l2tpv2_encap_conf = {
> +	.select_ipv4 = 1,
> +	.select_vlan = 0,
> +	.select_tos_ttl = 0,
> +	.flags_version = 0,
> +	.session_id = 0,
> +	.udp_src = 0,
> +	.udp_dst = 1701,
> +	.ipv4_src = RTE_IPV4(127, 0, 0, 1),
> +	.ipv4_dst = RTE_IPV4(255, 255, 255, 255),
> +	.ipv6_src = "\x00\x00\x00\x00\x00\x00\x00\x00"
> +		"\x00\x00\x00\x00\x00\x00\x00\x01",
> +	.ipv6_dst = "\x00\x00\x00\x00\x00\x00\x00\x00"
> +		"\x00\x00\x00\x00\x00\x00\x11\x11",
> +	.vlan_tci = 0,
> +	.ip_tos = 0,
> +	.ip_ttl = 255,
> +	.eth_src = "\x00\x00\x00\x00\x00\x00",
> +	.eth_dst = "\xff\xff\xff\xff\xff\xff", };
> +
> +/** Maximum number of items in struct rte_flow_action_l2tpv2_encap. */
> +#define ACTION_L2TPV2_ENCAP_ITEMS_NUM 6
> +
> +/** Storage for struct rte_flow_action_l2tpv2_encap including external
> +data. */ struct action_l2tpv2_encap_data {
> +	struct rte_flow_action_l2tpv2_encap conf;
> +	struct rte_flow_item items[ACTION_L2TPV2_ENCAP_ITEMS_NUM];
> +	struct rte_flow_item_eth item_eth;
> +	struct rte_flow_item_vlan item_vlan;
> +	union {
> +		struct rte_flow_item_ipv4 item_ipv4;
> +		struct rte_flow_item_ipv6 item_ipv6;
> +	};
> +	struct rte_flow_item_udp item_udp;
> +	struct rte_flow_item_l2tpv2 item_l2tpv2; };
> +
>  struct l2_encap_conf l2_encap_conf;
> 

See my comment at the top.

>  struct l2_decap_conf l2_decap_conf;
> @@ -614,6 +671,7 @@ struct rte_flow_action_port_id
> sample_port_id[RAW_SAMPLE_CONFS_MAX_NUM];
>  struct rte_flow_action_raw_encap sample_encap[RAW_SAMPLE_CONFS_MAX_NUM];
>  struct action_vxlan_encap_data sample_vxlan_encap[RAW_SAMPLE_CONFS_MAX_NUM];
>  struct action_nvgre_encap_data sample_nvgre_encap[RAW_SAMPLE_CONFS_MAX_NUM];
> +struct action_l2tpv2_encap_data
> +sample_l2tpv2_encap[RAW_SAMPLE_CONFS_MAX_NUM];
>  struct action_rss_data sample_rss_data[RAW_SAMPLE_CONFS_MAX_NUM];
>  struct rte_flow_action_vf sample_vf[RAW_SAMPLE_CONFS_MAX_NUM];
> 
> @@ -999,6 +1057,8 @@ static const enum index next_item[] = {
>  	ITEM_GENEVE_OPT,
>  	ITEM_INTEGRITY,
>  	ITEM_CONNTRACK,
> +	ITEM_L2TPV2,
> +	ITEM_PPP,
>  	END_SET,
>  	ZERO,
>  };
> @@ -1367,6 +1427,31 @@ static const enum index item_integrity_lv[] = {
>  	ZERO,
>  };
> 
> +static const enum index item_l2tpv2[] = {
> +	ITEM_L2TPV2_COMMON,
> +	ITEM_NEXT,
> +	ZERO,
> +};
> +
> +static const enum index item_l2tpv2_common[] = {
> +	ITEM_L2TPV2_COMMON_TYPE,
> +	ZERO,
> +};
> +
> +static const enum index item_l2tpv2_common_type[] = {
> +	ITEM_L2TPV2_COMMON_TYPE_DATA_L,
> +	ITEM_L2TPV2_COMMON_TYPE_CTRL,
> +	ZERO,
> +};
> +
> +static const enum index item_ppp[] = {
> +	ITEM_PPP_ADDR,
> +	ITEM_PPP_CTRL,
> +	ITEM_PPP_PROTO_ID,
> +	ITEM_NEXT,
> +	ZERO,
> +};
> +
>  static const enum index next_action[] = {
>  	ACTION_END,
>  	ACTION_VOID,
> @@ -1400,6 +1485,8 @@ static const enum index next_action[] = {
>  	ACTION_VXLAN_DECAP,
>  	ACTION_NVGRE_ENCAP,
>  	ACTION_NVGRE_DECAP,
> +	ACTION_L2TPV2_ENCAP,
> +	ACTION_L2TPV2_DECAP,
>  	ACTION_L2_ENCAP,
>  	ACTION_L2_DECAP,
>  	ACTION_MPLSOGRE_ENCAP,
> @@ -1687,6 +1774,7 @@ static const enum index next_action_sample[] = {
>  	ACTION_RAW_ENCAP,
>  	ACTION_VXLAN_ENCAP,
>  	ACTION_NVGRE_ENCAP,
> +	ACTION_L2TPV2_ENCAP,
>  	ACTION_NEXT,
>  	ZERO,
>  };
> @@ -1757,6 +1845,9 @@ static int parse_vc_action_vxlan_encap(struct context *, const struct token
> *,  static int parse_vc_action_nvgre_encap(struct context *, const struct token *,
>  				       const char *, unsigned int, void *,
>  				       unsigned int);
> +static int parse_vc_action_l2tpv2_encap(struct context *, const struct token *,
> +					const char *, unsigned int, void *,
> +					unsigned int);
>  static int parse_vc_action_l2_encap(struct context *, const struct token *,
>  				    const char *, unsigned int, void *,
>  				    unsigned int);
> @@ -3606,6 +3697,136 @@ static const struct token token_list[] = {
>  			     item_param),
>  		.args = ARGS(ARGS_ENTRY(struct rte_flow_item_conntrack, flags)),
>  	},
> +	[ITEM_L2TPV2] = {
> +		.name = "l2tpv2",
> +		.help = "match l2tpv2 header",
> +		.priv = PRIV_ITEM(L2TPV2, sizeof(struct rte_flow_item_l2tpv2)),
> +		.next = NEXT(item_l2tpv2),
> +		.call = parse_vc,
> +	},
> +	[ITEM_L2TPV2_COMMON] = {
> +		.name = "common",
> +		.help = "l2tpv2 common header",
> +		.next = NEXT(item_l2tpv2_common),
> +	},
> +	[ITEM_L2TPV2_COMMON_TYPE] = {
> +		.name = "type",
> +		.help = "type of common header",
> +		.next = NEXT(item_l2tpv2_common_type),
> +		.args = ARGS(ARG_ENTRY_HTON(struct rte_flow_item_l2tpv2)),
> +	},
> +	[ITEM_L2TPV2_COMMON_TYPE_DATA_L] = {
> +		.name = "data_l",
> +		.help = "Type #6: data message with length option",
> +		.next = NEXT(NEXT_ENTRY(ITEM_L2TPV2_MSG_DATA_L_LENGTH,
> +					ITEM_L2TPV2_MSG_DATA_L_TUNNEL_ID,
> +					ITEM_L2TPV2_MSG_DATA_L_SESSION_ID,
> +					ITEM_NEXT)),
> +		.call = parse_vc,
> +	},
> +	[ITEM_L2TPV2_MSG_DATA_L_LENGTH] = {
> +		.name = "length",
> +		.help = "message length",
> +		.next = NEXT(item_l2tpv2, NEXT_ENTRY(COMMON_UNSIGNED),
> +			     item_param),
> +		.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2,
> +					     hdr.type7.tunnel_id)),
> +	},
> +	[ITEM_L2TPV2_MSG_DATA_L_TUNNEL_ID] = {
> +		.name = "tunnel_id",
> +		.help = "tunnel identifier",
> +		.next = NEXT(item_l2tpv2, NEXT_ENTRY(COMMON_UNSIGNED),
> +			     item_param),
> +		.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2,
> +					     hdr.type7.tunnel_id)),
> +	},
> +	[ITEM_L2TPV2_MSG_DATA_L_SESSION_ID] = {
> +		.name = "session_id",
> +		.help = "session identifier",
> +		.next = NEXT(item_l2tpv2, NEXT_ENTRY(COMMON_UNSIGNED),
> +			     item_param),
> +		.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2,
> +					     hdr.type7.session_id)),
> +	},
> +	[ITEM_L2TPV2_COMMON_TYPE_CTRL] = {
> +		.name = "control",
> +		.help = "Type #3: conrtol message contains length, ns, nr options",
> +		.next = NEXT(NEXT_ENTRY(ITEM_L2TPV2_MSG_CTRL_LENGTH,
> +					ITEM_L2TPV2_MSG_CTRL_TUNNEL_ID,
> +					ITEM_L2TPV2_MSG_CTRL_SESSION_ID,
> +					ITEM_L2TPV2_MSG_CTRL_NS,
> +					ITEM_L2TPV2_MSG_CTRL_NR,
> +					ITEM_NEXT)),
> +		.call = parse_vc,
> +	},
> +	[ITEM_L2TPV2_MSG_CTRL_LENGTH] = {
> +		.name = "length",
> +		.help = "message length",
> +		.next = NEXT(item_l2tpv2, NEXT_ENTRY(COMMON_UNSIGNED),
> +			     item_param),
> +		.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2,
> +					     hdr.type3.length)),
> +	},
> +	[ITEM_L2TPV2_MSG_CTRL_TUNNEL_ID] = {
> +		.name = "tunnel_id",
> +		.help = "tunnel identifier",
> +		.next = NEXT(item_l2tpv2, NEXT_ENTRY(COMMON_UNSIGNED),
> +			     item_param),
> +		.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2,
> +					     hdr.type3.tunnel_id)),
> +	},
> +	[ITEM_L2TPV2_MSG_CTRL_SESSION_ID] = {
> +		.name = "session_id",
> +		.help = "session identifier",
> +		.next = NEXT(item_l2tpv2, NEXT_ENTRY(COMMON_UNSIGNED),
> +			     item_param),
> +		.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2,
> +					     hdr.type3.session_id)),
> +	},
> +	[ITEM_L2TPV2_MSG_CTRL_NS] = {
> +		.name = "ns",
> +		.help = "sequence number for message",
> +		.next = NEXT(item_l2tpv2, NEXT_ENTRY(COMMON_UNSIGNED),
> +			     item_param),
> +		.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2,
> +					     hdr.type3.ns)),
> +	},
> +	[ITEM_L2TPV2_MSG_CTRL_NR] = {
> +		.name = "nr",
> +		.help = "sequence number for next receive message",
> +		.next = NEXT(item_l2tpv2, NEXT_ENTRY(COMMON_UNSIGNED),
> +			     item_param),
> +		.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2,
> +					     hdr.type3.nr)),
> +	},
> +	[ITEM_PPP] = {
> +		.name = "ppp",
> +		.help = "match ppp header",
> +		.priv = PRIV_ITEM(PPP, sizeof(struct rte_flow_item_ppp)),
> +		.next = NEXT(item_ppp),
> +		.call = parse_vc,
> +	},
> +	[ITEM_PPP_ADDR] = {
> +		.name = "addr",
> +		.help = "ppp address",
> +		.next = NEXT(item_ppp, NEXT_ENTRY(COMMON_UNSIGNED),
> +			     item_param),
> +		.args = ARGS(ARGS_ENTRY(struct rte_flow_item_ppp, addr)),
> +	},
> +	[ITEM_PPP_CTRL] = {
> +		.name = "ctrl",
> +		.help = "ppp control",
> +		.next = NEXT(item_ppp, NEXT_ENTRY(COMMON_UNSIGNED),
> +			     item_param),
> +		.args = ARGS(ARGS_ENTRY(struct rte_flow_item_ppp, ctrl)),
> +	},
> +	[ITEM_PPP_PROTO_ID] = {
> +		.name = "proto_id",
> +		.help = "ppp protocol id",
> +		.next = NEXT(item_ppp, NEXT_ENTRY(COMMON_UNSIGNED),
> +			     item_param),
> +		.args = ARGS(ARGS_ENTRY(struct rte_flow_item_ppp, proto_id)),
> +	},
>  	/* Validate/create actions. */
>  	[ACTIONS] = {
>  		.name = "actions",
> @@ -4125,6 +4346,24 @@ static const struct token token_list[] = {
>  		.next = NEXT(NEXT_ENTRY(ACTION_NEXT)),
>  		.call = parse_vc,
>  	},
> +	[ACTION_L2TPV2_ENCAP] = {
> +		.name = "l2tpv2_encap",
> +		.help = "L2TPV2 encapsulation, uses configuration set by \"set"
> +			" l2tpv2\"",
> +		.priv = PRIV_ACTION(L2TPV2_ENCAP,
> +				    sizeof(struct action_l2tpv2_encap_data)),
> +		.next = NEXT(NEXT_ENTRY(ACTION_NEXT)),
> +		.call = parse_vc_action_l2tpv2_encap,
> +	},
> +	[ACTION_L2TPV2_DECAP] = {
> +		.name = "l2tpv2_decap",
> +		.help = "Performs a decapsulation action by stripping all"
> +			" headers of the L2TPV2 tunnel network overlay from the"
> +			" matched flow.",
> +		.priv = PRIV_ACTION(L2TPV2_DECAP, 0),
> +		.next = NEXT(NEXT_ENTRY(ACTION_NEXT)),
> +		.call = parse_vc,
> +	},
>  	[ACTION_L2_ENCAP] = {
>  		.name = "l2_encap",
>  		.help = "l2 encap, uses configuration set by"
> @@ -5907,6 +6146,152 @@ parse_vc_action_nvgre_encap(struct context *ctx, const struct token
> *token,
>  	return ret;
>  }
> 
> +/** Setup L2TPV2 encap configuration. */ static int
> +parse_setup_l2tpv2_encap_data(struct action_l2tpv2_encap_data
> +*action_l2tpv2_encap_data) {
> +	/* Set up default configuration. */
> +	*action_l2tpv2_encap_data = (struct action_l2tpv2_encap_data){
> +		.conf = (struct rte_flow_action_l2tpv2_encap){
> +			.definition = action_l2tpv2_encap_data->items,
> +		},
> +		.items = {
> +			{
> +				.type = RTE_FLOW_ITEM_TYPE_ETH,
> +				.spec = &action_l2tpv2_encap_data->item_eth,
> +				.mask = &rte_flow_item_eth_mask,
> +			},
> +			{
> +				.type = RTE_FLOW_ITEM_TYPE_VLAN,
> +				.spec = &action_l2tpv2_encap_data->item_vlan,
> +				.mask = &rte_flow_item_vlan_mask,
> +			},
> +			{
> +				.type = RTE_FLOW_ITEM_TYPE_IPV4,
> +				.spec = &action_l2tpv2_encap_data->item_ipv4,
> +				.mask = &rte_flow_item_ipv4_mask,
> +			},
> +			{
> +				.type = RTE_FLOW_ITEM_TYPE_UDP,
> +				.spec = &action_l2tpv2_encap_data->item_udp,
> +				.mask = &rte_flow_item_udp_mask,
> +			},
> +			{
> +				.type = RTE_FLOW_ITEM_TYPE_L2TPV2,
> +				.spec = &action_l2tpv2_encap_data->item_l2tpv2,
> +				.mask = &rte_flow_item_l2tpv2_mask,
> +			},
> +			{
> +				.type = RTE_FLOW_ITEM_TYPE_END,
> +			},
> +		},
> +		.item_eth.type = 0,
> +		.item_vlan = {
> +			.tci = l2tpv2_encap_conf.vlan_tci,
> +			.inner_type = 0,
> +		},
> +		.item_ipv4.hdr = {
> +			.src_addr = l2tpv2_encap_conf.ipv4_src,
> +			.dst_addr = l2tpv2_encap_conf.ipv4_dst,
> +		},
> +		.item_udp.hdr = {
> +			.src_port = l2tpv2_encap_conf.udp_src,
> +			.dst_port = l2tpv2_encap_conf.udp_dst,
> +		},
> +	};
> +	memcpy(action_l2tpv2_encap_data->item_eth.dst.addr_bytes,
> +	       l2tpv2_encap_conf.eth_dst, RTE_ETHER_ADDR_LEN);
> +	memcpy(action_l2tpv2_encap_data->item_eth.src.addr_bytes,
> +	       l2tpv2_encap_conf.eth_src, RTE_ETHER_ADDR_LEN);
> +	if (!l2tpv2_encap_conf.select_ipv4) {
> +		memcpy(&action_l2tpv2_encap_data->item_ipv6.hdr.src_addr,
> +		       &l2tpv2_encap_conf.ipv6_src,
> +		       sizeof(l2tpv2_encap_conf.ipv6_src));
> +		memcpy(&action_l2tpv2_encap_data->item_ipv6.hdr.dst_addr,
> +		       &l2tpv2_encap_conf.ipv6_dst,
> +		       sizeof(l2tpv2_encap_conf.ipv6_dst));
> +		action_l2tpv2_encap_data->items[2] = (struct rte_flow_item){
> +			.type = RTE_FLOW_ITEM_TYPE_IPV6,
> +			.spec = &action_l2tpv2_encap_data->item_ipv6,
> +			.mask = &rte_flow_item_ipv6_mask,
> +		};
> +	}
> +	if (!l2tpv2_encap_conf.select_vlan)
> +		action_l2tpv2_encap_data->items[1].type =
> +			RTE_FLOW_ITEM_TYPE_VOID;
> +	if (l2tpv2_encap_conf.select_tos_ttl) {
> +		if (l2tpv2_encap_conf.select_ipv4) {
> +			static struct rte_flow_item_ipv4 ipv4_mask_tos;
> +
> +			memcpy(&ipv4_mask_tos, &rte_flow_item_ipv4_mask,
> +			       sizeof(ipv4_mask_tos));
> +			ipv4_mask_tos.hdr.type_of_service = 0xff;
> +			ipv4_mask_tos.hdr.time_to_live = 0xff;
> +			action_l2tpv2_encap_data->item_ipv4.hdr.type_of_service =
> +					l2tpv2_encap_conf.ip_tos;
> +			action_l2tpv2_encap_data->item_ipv4.hdr.time_to_live =
> +					l2tpv2_encap_conf.ip_ttl;
> +			action_l2tpv2_encap_data->items[2].mask =
> +							&ipv4_mask_tos;
> +		} else {
> +			static struct rte_flow_item_ipv6 ipv6_mask_tos;
> +
> +			memcpy(&ipv6_mask_tos, &rte_flow_item_ipv6_mask,
> +			       sizeof(ipv6_mask_tos));
> +			ipv6_mask_tos.hdr.vtc_flow |=
> +				RTE_BE32(0xfful << RTE_IPV6_HDR_TC_SHIFT);
> +			ipv6_mask_tos.hdr.hop_limits = 0xff;
> +			action_l2tpv2_encap_data->item_ipv6.hdr.vtc_flow |=
> +				rte_cpu_to_be_32
> +					((uint32_t)l2tpv2_encap_conf.ip_tos <<
> +					 RTE_IPV6_HDR_TC_SHIFT);
> +			action_l2tpv2_encap_data->item_ipv6.hdr.hop_limits =
> +					l2tpv2_encap_conf.ip_ttl;
> +			action_l2tpv2_encap_data->items[2].mask =
> +							&ipv6_mask_tos;
> +		}
> +	}
> +
> +	if (0xc800 == (l2tpv2_encap_conf.flags_version & 0xcb00)) {
> +		action_l2tpv2_encap_data->item_l2tpv2.hdr.type3.session_id =
> +			l2tpv2_encap_conf.session_id;
> +	} else if (0x4000 == (l2tpv2_encap_conf.flags_version & 0xcb00)) {
> +		action_l2tpv2_encap_data->item_l2tpv2.hdr.type6.session_id =
> +			l2tpv2_encap_conf.session_id;
> +	}
> +
> +	return 0;
> +}
> +
> +/** Parse l2tpv2 encap action. */
> +static int
> +parse_vc_action_l2tpv2_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_l2tpv2_encap_data *action_l2tpv2_encap_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;
> +	action_l2tpv2_encap_data = ctx->object;
> +	parse_setup_l2tpv2_encap_data(action_l2tpv2_encap_data);
> +	action->conf = &action_l2tpv2_encap_data->conf;
> +	return ret;
> +}
> +
>  /** Parse l2 encap action. */
>  static int
>  parse_vc_action_l2_encap(struct context *ctx, const struct token *token, @@ -8333,6 +8718,12 @@
> flow_item_default_mask(const struct rte_flow_item *item)
>  	case RTE_FLOW_ITEM_TYPE_PFCP:
>  		mask = &rte_flow_item_pfcp_mask;
>  		break;
> +	case RTE_FLOW_ITEM_TYPE_L2TPV2:
> +		mask = &rte_flow_item_l2tpv2_mask;
> +		break;
> +	case RTE_FLOW_ITEM_TYPE_PPP:
> +		mask = &rte_flow_item_ppp_mask;
> +		break;
>  	default:
>  		break;
>  	}
> @@ -8432,6 +8823,11 @@ cmd_set_raw_parsed_sample(const struct buffer *in)
>  			parse_setup_nvgre_encap_data(&sample_nvgre_encap[idx]);
>  			action->conf = &sample_nvgre_encap[idx];
>  			break;
> +		case RTE_FLOW_ACTION_TYPE_L2TPV2_ENCAP:
> +			size = sizeof(struct rte_flow_action_l2tpv2_encap);
> +			parse_setup_l2tpv2_encap_data(&sample_l2tpv2_encap[idx]);
> +			action->conf = &sample_l2tpv2_encap[idx];
> +			break;
>  		default:
>  			fprintf(stderr, "Error - Not supported action\n");
>  			return;
> diff --git a/app/test-pmd/testpmd.h b/app/test-pmd/testpmd.h index e9d9db06ce..c744799b46
> 100644
> --- a/app/test-pmd/testpmd.h
> +++ b/app/test-pmd/testpmd.h
> @@ -567,6 +567,28 @@ struct nvgre_encap_conf {
> 
>  extern struct nvgre_encap_conf nvgre_encap_conf;
> 
> +/* L2TPV2 encap/decap parameters. */
> +struct l2tpv2_encap_conf {
> +	uint32_t select_ipv4:1;
> +	uint32_t select_vlan:1;
> +	uint32_t select_tos_ttl:1;
> +	rte_be16_t flags_version;
> +	rte_be16_t session_id;
> +	rte_be16_t udp_src;
> +	rte_be16_t udp_dst;
> +	rte_be32_t ipv4_src;
> +	rte_be32_t ipv4_dst;
> +	uint8_t ipv6_src[16];
> +	uint8_t ipv6_dst[16];
> +	rte_be16_t vlan_tci;
> +	uint8_t ip_tos;
> +	uint8_t ip_ttl;
> +	uint8_t eth_src[RTE_ETHER_ADDR_LEN];
> +	uint8_t eth_dst[RTE_ETHER_ADDR_LEN];
> +};
> +
> +extern struct l2tpv2_encap_conf l2tpv2_encap_conf;
> +
>  /* L2 encap parameters. */
>  struct l2_encap_conf {
>  	uint32_t select_ipv4:1;
> --
> 2.25.1

Best,
Ori


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

* [dpdk-dev] [PATCH v4 0/3] support PPPoL2TPv2oUDP RSS Hash
  2021-10-15  9:58   ` [dpdk-dev] [PATCH v3 0/3] " Jie Wang
                       ` (2 preceding siblings ...)
  2021-10-15  9:58     ` [dpdk-dev] [PATCH v3 3/3] app/testpmd: support L2TPV2 and PPP protocol pattern Jie Wang
@ 2021-10-18  9:33     ` Jie Wang
  2021-10-18  9:33       ` [dpdk-dev] [PATCH v4 1/3] ethdev: support PPP and L2TPV2 procotol Jie Wang
                         ` (3 more replies)
  3 siblings, 4 replies; 71+ messages in thread
From: Jie Wang @ 2021-10-18  9:33 UTC (permalink / raw)
  To: dev
  Cc: orika, ferruh.yigit, thomas, andrew.rybchenko, xiaoyun.li,
	stevex.yang, jingjing.wu, beilei.xing, wenjun1.wu, qi.z.zhang,
	Jie Wang

Support IAVF PPPoL2TPv2oUDP RSS Hash. Required to distribute packets
based on inner IP src+dest address and TCP/UDP src+dest port.

---
v4:
 * update commit log.
 * redefine PPP protocol header.
 * delete l2tpv2_encap.
v3:
 * add testpmd match ppp and l2tpv2 protocol header fields value.
 * add the code of l2tpv2_encap.
 * update the title of ethdev patch and adjust the position of
   the added code.

v2:
 * update the rte_flow.rst and release notes.
 * update l2tpv2 header format.

Jie Wang (3):
  ethdev: support PPP and L2TPV2 procotol
  net/iavf: support PPPoL2TPv2oUDP RSS Hash
  app/testpmd: support L2TPV2 and PPP protocol pattern

 app/test-pmd/cmdline_flow.c            | 251 +++++++++++++++++++++++++
 doc/guides/prog_guide/rte_flow.rst     |  25 +++
 doc/guides/rel_notes/release_21_11.rst |   5 +
 drivers/net/iavf/iavf_generic_flow.c   | 131 +++++++++++++
 drivers/net/iavf/iavf_generic_flow.h   |  15 ++
 drivers/net/iavf/iavf_hash.c           | 108 ++++++++++-
 lib/ethdev/rte_flow.c                  |   2 +
 lib/ethdev/rte_flow.h                  |  66 +++++++
 lib/net/rte_l2tpv2.h                   | 214 +++++++++++++++++++++
 lib/net/rte_ppp.h                      |  35 ++++
 10 files changed, 850 insertions(+), 2 deletions(-)
 create mode 100644 lib/net/rte_l2tpv2.h
 create mode 100644 lib/net/rte_ppp.h

-- 
2.25.1


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

* [dpdk-dev] [PATCH v4 1/3] ethdev: support PPP and L2TPV2 procotol
  2021-10-18  9:33     ` [dpdk-dev] [PATCH v4 0/3] support PPPoL2TPv2oUDP RSS Hash Jie Wang
@ 2021-10-18  9:33       ` Jie Wang
  2021-10-18 10:56         ` Ori Kam
  2021-10-18  9:33       ` [dpdk-dev] [PATCH v4 2/3] net/iavf: support PPPoL2TPv2oUDP RSS Hash Jie Wang
                         ` (2 subsequent siblings)
  3 siblings, 1 reply; 71+ messages in thread
From: Jie Wang @ 2021-10-18  9:33 UTC (permalink / raw)
  To: dev
  Cc: orika, ferruh.yigit, thomas, andrew.rybchenko, xiaoyun.li,
	stevex.yang, jingjing.wu, beilei.xing, wenjun1.wu, qi.z.zhang,
	Jie Wang

Added flow pattern items and header formats of L2TPv2 and PPP.

Signed-off-by: Wenjun Wu <wenjun1.wu@intel.com>
Signed-off-by: Jie Wang <jie1x.wang@intel.com>
---
 doc/guides/prog_guide/rte_flow.rst     |  25 +++
 doc/guides/rel_notes/release_21_11.rst |   5 +
 lib/ethdev/rte_flow.c                  |   2 +
 lib/ethdev/rte_flow.h                  |  66 ++++++++
 lib/net/rte_l2tpv2.h                   | 214 +++++++++++++++++++++++++
 lib/net/rte_ppp.h                      |  35 ++++
 6 files changed, 347 insertions(+)
 create mode 100644 lib/net/rte_l2tpv2.h
 create mode 100644 lib/net/rte_ppp.h

diff --git a/doc/guides/prog_guide/rte_flow.rst b/doc/guides/prog_guide/rte_flow.rst
index fa05fe0845..6277c641ef 100644
--- a/doc/guides/prog_guide/rte_flow.rst
+++ b/doc/guides/prog_guide/rte_flow.rst
@@ -1548,6 +1548,31 @@ This item is meant to use the same structure as `Item: PORT_REPRESENTOR`_.
 
 See also `Action: REPRESENTED_PORT`_.
 
+Item: ``L2TPV2``
+^^^^^^^^^^^^^^^^^^^
+
+Matches a L2TPv2 header.
+
+- ``flags_version``: flags(12b), version(4b).
+- ``length``: total length of the message.
+- ``tunnel_id``: identifier for the control connection.
+- ``session_id``: identifier for a session within a tunnel.
+- ``ns``: sequence number for this date or control message.
+- ``nr``: sequence number expected in the next control message to be received.
+- ``offset_size``: offset of payload data.
+- ``offset_padding``: offset padding, variable length.
+- Default ``mask`` matches flags_version only.
+
+Item: ``PPP``
+^^^^^^^^^^^^^^^^^^^
+
+Matches a PPP header.
+
+- ``addr``: ppp address.
+- ``ctrl``: ppp control.
+- ``proto_id``: ppp protocol identifier.
+- Default ``mask`` matches addr, ctrl, proto_id.
+
 Actions
 ~~~~~~~
 
diff --git a/doc/guides/rel_notes/release_21_11.rst b/doc/guides/rel_notes/release_21_11.rst
index ec2a788789..e1b23ce0e9 100644
--- a/doc/guides/rel_notes/release_21_11.rst
+++ b/doc/guides/rel_notes/release_21_11.rst
@@ -98,6 +98,11 @@ New Features
 
   Added an ethdev API which can help users get device configuration.
 
+* **Added L2TPV2 and PPP protocol support in rte_flow.**
+
+  Added flow pattern items and header formats of L2TPv2 and PPP to support
+  PPP over L2TPv2 over UDP protocol RSS Hash.
+
 * **Updated AF_XDP PMD.**
 
   * Disabled secondary process support.
diff --git a/lib/ethdev/rte_flow.c b/lib/ethdev/rte_flow.c
index 29f2b0e954..0bfbeb73e8 100644
--- a/lib/ethdev/rte_flow.c
+++ b/lib/ethdev/rte_flow.c
@@ -102,6 +102,8 @@ static const struct rte_flow_desc_data rte_flow_desc_item[] = {
 	MK_FLOW_ITEM(CONNTRACK, sizeof(uint32_t)),
 	MK_FLOW_ITEM(PORT_REPRESENTOR, sizeof(struct rte_flow_item_ethdev)),
 	MK_FLOW_ITEM(REPRESENTED_PORT, sizeof(struct rte_flow_item_ethdev)),
+	MK_FLOW_ITEM(L2TPV2, sizeof(struct rte_flow_item_l2tpv2)),
+	MK_FLOW_ITEM(PPP, sizeof(struct rte_flow_item_ppp)),
 };
 
 /** Generate flow_action[] entry. */
diff --git a/lib/ethdev/rte_flow.h b/lib/ethdev/rte_flow.h
index d5bfdaaaf2..2bc825b567 100644
--- a/lib/ethdev/rte_flow.h
+++ b/lib/ethdev/rte_flow.h
@@ -35,6 +35,8 @@
 #include <rte_mbuf_dyn.h>
 #include <rte_meter.h>
 #include <rte_gtp.h>
+#include <rte_l2tpv2.h>
+#include <rte_ppp.h>
 
 #ifdef __cplusplus
 extern "C" {
@@ -635,6 +637,21 @@ enum rte_flow_item_type {
 	 * @see struct rte_flow_item_ethdev
 	 */
 	RTE_FLOW_ITEM_TYPE_REPRESENTED_PORT,
+
+	/**
+	 * Matches L2TPV2 Header.
+	 *
+	 * See struct rte_flow_item_l2tpv2.
+	 */
+	RTE_FLOW_ITEM_TYPE_L2TPV2,
+
+	/**
+	 * Matches PPP Header.
+	 *
+	 * See struct rte_flow_item_ppp.
+	 */
+	RTE_FLOW_ITEM_TYPE_PPP,
+
 };
 
 /**
@@ -1891,6 +1908,55 @@ static const struct rte_flow_item_ethdev rte_flow_item_ethdev_mask = {
 };
 #endif
 
+/**
+ * @warning
+ * @b EXPERIMENTAL: this structure may change without prior notice
+ * RTE_FLOW_ITEM_TYPE_L2TPV2
+ *
+ * Matches L2TPv2 Header
+ */
+struct rte_flow_item_l2tpv2 {
+	struct rte_l2tpv2_combined_msg_hdr hdr;
+};
+
+/** Default mask for RTE_FLOW_ITEM_TYPE_L2TPV2. */
+#ifndef __cplusplus
+static const struct rte_flow_item_l2tpv2 rte_flow_item_l2tpv2_mask = {
+	/*
+	 * flags and version bit mask
+	 * 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0
+	 * T L x x S x O P x x x x V V V V
+	 */
+	.hdr = {
+		.common = {
+			.flags_version = 0xcb0f,
+		},
+	},
+};
+#endif
+
+/**
+ * @warning
+ * @b EXPERIMENTAL: this structure may change without prior notice
+ * RTE_FLOW_ITEM_TYPE_PPP
+ *
+ * Matches PPP Header
+ */
+struct rte_flow_item_ppp {
+	struct rte_ppp_hdr hdr;
+};
+
+/** Default mask for RTE_FLOW_ITEM_TYPE_PPP. */
+#ifndef __cplusplus
+static const struct rte_flow_item_ppp rte_flow_item_ppp_mask = {
+	.hdr = {
+		.addr = 0xff,
+		.ctrl = 0xff,
+		.proto_id = 0xffff,
+	}
+};
+#endif
+
 /**
  * Matching pattern item definition.
  *
diff --git a/lib/net/rte_l2tpv2.h b/lib/net/rte_l2tpv2.h
new file mode 100644
index 0000000000..aea3c689be
--- /dev/null
+++ b/lib/net/rte_l2tpv2.h
@@ -0,0 +1,214 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright 2021 Mellanox Technologies, Ltd
+ */
+
+#ifndef _RTE_L2TPV2_H_
+#define _RTE_L2TPV2_H_
+
+/**
+ * @file
+ *
+ * L2TP header:
+ *  0                   1                   2                   3
+ *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |T|L|x|x|S|x|O|P|x|x|x|x|  Ver  |          Length (opt)         |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |           Tunnel ID           |           Session ID          |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |             Ns (opt)          |             Nr (opt)          |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |      Offset Size (opt)        |    Offset pad... (opt)
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *
+ * The Type (T) bit indicates the type of message. It is set to 0 for a data
+ * message and 1 for a control message.
+ *
+ * If the Length (L) bit is 1, the Length field is present. This bit MUST be
+ * set to 1 for control messages.
+ *
+ * The x bits are reserved for future extensions. All reserved bits MUST
+ * be set to 0 on outgoing messages and ignored on incoming messages.
+ *
+ * If the Sequence (S) bit is set to 1 the Ns and Nr fields are present.
+ * The S bit MUST be set to 1 for control messages.
+ *
+ * If the Offset (O) bit is 1, the Offset Size field is present. The O
+ * bit MUST be set to 0 for control messages.
+ *
+ * If the Priority (P) bit is 1, this data message should receive
+ * preferential treatment in its local queuing and transmission.
+ * The P bit MUST be set to 0 for control messages.
+ *
+ * Ver MUST be 2, indicating the version of the L2TP data message header.
+ *
+ * The Length field indicates the total length of the message in octets.
+ *
+ * Tunnel ID indicates the identifier for the control connection.
+ *
+ * Session ID indicates the identifier for a session within a tunnel.
+ *
+ * Ns indicates the sequence number for this data or control message.
+ *
+ * Nr indicates the sequence number expected in the next control message
+ * to be received.
+ *
+ * The Offset Size field, if present, specifies the number of octets
+ * past the L2TP header at which the payload data is expected to start.
+ * Actual data within the offset padding is undefined. If the offset
+ * field is present, the L2TP header ends after the last octet of the
+ * offset padding.
+ */
+
+#include <stdint.h>
+#include <rte_byteorder.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * L2TPv2 Common Header
+ */
+RTE_STD_C11
+struct rte_l2tpv2_common_hdr {
+	union {
+		rte_be16_t flags_version;
+		struct {
+#if RTE_BYTE_ORDER == RTE_LITTLE_ENDIAN
+			rte_be16_t t:1;		/**< message Type */
+			rte_be16_t l:1;		/**< length option bit*/
+			rte_be16_t res1:2;	/**< reserved */
+			rte_be16_t s:1;		/**< ns/nr option bit*/
+			rte_be16_t res2:1;	/**< reserved */
+			rte_be16_t o:1;		/**< offset option bit*/
+			rte_be16_t p:1;		/**< priority option bit*/
+			rte_be16_t res3:4;	/**< reserved */
+			rte_be16_t ver:4;	/**< protocol version */
+#elif RTE_BYTE_ORDER == RTE_BIG_ENDIAN
+			rte_be16_t ver:4;	/**< protocol version */
+			rte_be16_t res3:4;	/**< reserved */
+			rte_be16_t p:1;		/**< priority option bit*/
+			rte_be16_t o:1;		/**< offset option bit*/
+			rte_be16_t res2:1;	/**< reserved */
+			rte_be16_t s:1;		/**< ns/nr option bit*/
+			rte_be16_t res1:2;	/**< reserved */
+			rte_be16_t l:1;		/**< length option bit*/
+			rte_be16_t t:1;		/**< message Type */
+#endif
+		};
+	};
+};
+
+/*
+ * L2TPv2 message Header contains all options(length, ns, nr,
+ * offset size, offset padding).
+ */
+struct rte_l2tpv2_msg_with_all_options {
+	rte_be16_t length;		/**< length(16) */
+	rte_be16_t tunnel_id;		/**< tunnel id(16) */
+	rte_be16_t session_id;		/**< session id(16) */
+	rte_be16_t ns;			/**< Ns(16) */
+	rte_be16_t nr;			/**< Nr(16) */
+	rte_be16_t offset_size;		/**< offset size(16) */
+	uint8_t   *offset_padding;	/**< offset padding(variable length) */
+};
+
+/*
+ * L2TPv2 message Header contains all options except length(ns, nr,
+ * offset size, offset padding).
+ */
+struct rte_l2tpv2_msg_without_length {
+	rte_be16_t tunnel_id;		/**< tunnel id(16) */
+	rte_be16_t session_id;		/**< session id(16) */
+	rte_be16_t ns;			/**< Ns(16) */
+	rte_be16_t nr;			/**< Nr(16) */
+	rte_be16_t offset_size;		/**< offset size(16) */
+	uint8_t   *offset_padding;	/**< offset padding(variable length) */
+};
+
+/*
+ * L2TPv2 message Header contains all options except ns_nr(length,
+ * offset size, offset padding).
+ * Ns and Nr MUST be toghter.
+ */
+struct rte_l2tpv2_msg_without_ns_nr {
+	rte_be16_t length;		/**< length(16) */
+	rte_be16_t tunnel_id;		/**< tunnel id(16) */
+	rte_be16_t session_id;		/**< session id(16) */
+	rte_be16_t offset_size;		/**< offset size(16) */
+	uint8_t   *offset_padding;	/**< offset padding(variable length) */
+};
+
+/*
+ * L2TPv2 message Header contains all options except ns_nr(length, ns, nr).
+ * offset size and offset padding MUST be toghter.
+ */
+struct rte_l2tpv2_msg_without_offset {
+	rte_be16_t length;		/**< length(16) */
+	rte_be16_t tunnel_id;		/**< tunnel id(16) */
+	rte_be16_t session_id;		/**< session id(16) */
+	rte_be16_t ns;			/**< Ns(16) */
+	rte_be16_t nr;			/**< Nr(16) */
+};
+
+/*
+ * L2TPv2 message Header contains options offset size and offset padding.
+ */
+struct rte_l2tpv2_msg_with_offset {
+	rte_be16_t tunnel_id;		/**< tunnel id(16) */
+	rte_be16_t session_id;		/**< session id(16) */
+	rte_be16_t offset_size;		/**< offset size(16) */
+	uint8_t   *offset_padding;	/**< offset padding(variable length) */
+};
+
+/*
+ * L2TPv2 message Header contains options ns and nr.
+ */
+struct rte_l2tpv2_msg_with_ns_nr {
+	rte_be16_t tunnel_id;		/**< tunnel id(16) */
+	rte_be16_t session_id;		/**< session id(16) */
+	rte_be16_t ns;			/**< Ns(16) */
+	rte_be16_t nr;			/**< Nr(16) */
+};
+
+/*
+ * L2TPv2 message Header contains option length.
+ */
+struct rte_l2tpv2_msg_with_length {
+	rte_be16_t length;		/**< length(16) */
+	rte_be16_t tunnel_id;		/**< tunnel id(16) */
+	rte_be16_t session_id;		/**< session id(16) */
+};
+
+/*
+ * L2TPv2 message Header without all options.
+ */
+struct rte_l2tpv2_msg_without_all_options {
+	rte_be16_t tunnel_id;		/**< tunnel id(16) */
+	rte_be16_t session_id;		/**< session id(16) */
+};
+
+/**
+ * L2TPv2 Combined Message Header Format: Common Header + Options
+ */
+RTE_STD_C11
+struct rte_l2tpv2_combined_msg_hdr {
+	struct rte_l2tpv2_common_hdr common;
+	union {
+		struct rte_l2tpv2_msg_with_all_options type0;
+		struct rte_l2tpv2_msg_without_length type1;
+		struct rte_l2tpv2_msg_without_ns_nr type2;
+		struct rte_l2tpv2_msg_without_offset type3;
+		struct rte_l2tpv2_msg_with_offset type4;
+		struct rte_l2tpv2_msg_with_ns_nr type5;
+		struct rte_l2tpv2_msg_with_length type6;
+		struct rte_l2tpv2_msg_without_all_options type7;
+	};
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RTE_L2TPV2_H_ */
diff --git a/lib/net/rte_ppp.h b/lib/net/rte_ppp.h
new file mode 100644
index 0000000000..9ea633baa7
--- /dev/null
+++ b/lib/net/rte_ppp.h
@@ -0,0 +1,35 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright 2021 Mellanox Technologies, Ltd
+ */
+
+#ifndef _RTE_PPP_H_
+#define _RTE_PPP_H_
+
+/**
+ * @file
+ *
+ * PPP headers definition.
+ *
+ */
+
+#include <stdint.h>
+#include <rte_byteorder.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * PPP Header
+ */
+struct rte_ppp_hdr {
+	uint8_t addr; /**< ppp address(8) */
+	uint8_t ctrl; /**< ppp control(8) */
+	rte_be16_t proto_id; /**< ppp protocol id(16) */
+} __rte_packed;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RTE_PPP_H_ */
-- 
2.25.1


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

* [dpdk-dev] [PATCH v4 2/3] net/iavf: support PPPoL2TPv2oUDP RSS Hash
  2021-10-18  9:33     ` [dpdk-dev] [PATCH v4 0/3] support PPPoL2TPv2oUDP RSS Hash Jie Wang
  2021-10-18  9:33       ` [dpdk-dev] [PATCH v4 1/3] ethdev: support PPP and L2TPV2 procotol Jie Wang
@ 2021-10-18  9:33       ` Jie Wang
  2021-10-18  9:33       ` [dpdk-dev] [PATCH v4 3/3] app/testpmd: support L2TPV2 and PPP protocol pattern Jie Wang
  2021-10-19  3:08       ` [dpdk-dev] [PATCH v5 0/3] support PPPoL2TPv2oUDP RSS Hash Jie Wang
  3 siblings, 0 replies; 71+ messages in thread
From: Jie Wang @ 2021-10-18  9:33 UTC (permalink / raw)
  To: dev
  Cc: orika, ferruh.yigit, thomas, andrew.rybchenko, xiaoyun.li,
	stevex.yang, jingjing.wu, beilei.xing, wenjun1.wu, qi.z.zhang,
	Jie Wang

Add support for PPP over L2TPv2 over UDP protocol RSS Hash based
on inner IP src/dst address and TCP/UDP src/dst port.

Patterns are listed below:
eth/ipv4(6)/udp/l2tpv2/ppp/ipv4(6)
eth/ipv4(6)/udp/l2tpv2/ppp/ipv4(6)/udp
eth/ipv4(6)/udp/l2tpv2/ppp/ipv4(6)/tcp

Signed-off-by: Wenjun Wu <wenjun1.wu@intel.com>
Signed-off-by: Jie Wang <jie1x.wang@intel.com>
---
 drivers/net/iavf/iavf_generic_flow.c | 131 +++++++++++++++++++++++++++
 drivers/net/iavf/iavf_generic_flow.h |  15 +++
 drivers/net/iavf/iavf_hash.c         | 108 +++++++++++++++++++++-
 3 files changed, 252 insertions(+), 2 deletions(-)

diff --git a/drivers/net/iavf/iavf_generic_flow.c b/drivers/net/iavf/iavf_generic_flow.c
index b86d99e57d..364904fa02 100644
--- a/drivers/net/iavf/iavf_generic_flow.c
+++ b/drivers/net/iavf/iavf_generic_flow.c
@@ -1611,6 +1611,137 @@ enum rte_flow_item_type iavf_pattern_eth_ipv6_gre_ipv6_udp[] = {
 	RTE_FLOW_ITEM_TYPE_END,
 };
 
+/* PPPoL2TPv2oUDP */
+enum rte_flow_item_type iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv4[] = {
+	RTE_FLOW_ITEM_TYPE_ETH,
+	RTE_FLOW_ITEM_TYPE_IPV4,
+	RTE_FLOW_ITEM_TYPE_UDP,
+	RTE_FLOW_ITEM_TYPE_L2TPV2,
+	RTE_FLOW_ITEM_TYPE_PPP,
+	RTE_FLOW_ITEM_TYPE_IPV4,
+	RTE_FLOW_ITEM_TYPE_END,
+};
+
+enum rte_flow_item_type iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv6[] = {
+	RTE_FLOW_ITEM_TYPE_ETH,
+	RTE_FLOW_ITEM_TYPE_IPV4,
+	RTE_FLOW_ITEM_TYPE_UDP,
+	RTE_FLOW_ITEM_TYPE_L2TPV2,
+	RTE_FLOW_ITEM_TYPE_PPP,
+	RTE_FLOW_ITEM_TYPE_IPV6,
+	RTE_FLOW_ITEM_TYPE_END,
+};
+
+enum rte_flow_item_type iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv4_udp[] = {
+	RTE_FLOW_ITEM_TYPE_ETH,
+	RTE_FLOW_ITEM_TYPE_IPV4,
+	RTE_FLOW_ITEM_TYPE_UDP,
+	RTE_FLOW_ITEM_TYPE_L2TPV2,
+	RTE_FLOW_ITEM_TYPE_PPP,
+	RTE_FLOW_ITEM_TYPE_IPV4,
+	RTE_FLOW_ITEM_TYPE_UDP,
+	RTE_FLOW_ITEM_TYPE_END,
+};
+
+enum rte_flow_item_type iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv4_tcp[] = {
+	RTE_FLOW_ITEM_TYPE_ETH,
+	RTE_FLOW_ITEM_TYPE_IPV4,
+	RTE_FLOW_ITEM_TYPE_UDP,
+	RTE_FLOW_ITEM_TYPE_L2TPV2,
+	RTE_FLOW_ITEM_TYPE_PPP,
+	RTE_FLOW_ITEM_TYPE_IPV4,
+	RTE_FLOW_ITEM_TYPE_TCP,
+	RTE_FLOW_ITEM_TYPE_END,
+};
+
+enum rte_flow_item_type iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv6_udp[] = {
+	RTE_FLOW_ITEM_TYPE_ETH,
+	RTE_FLOW_ITEM_TYPE_IPV4,
+	RTE_FLOW_ITEM_TYPE_UDP,
+	RTE_FLOW_ITEM_TYPE_L2TPV2,
+	RTE_FLOW_ITEM_TYPE_PPP,
+	RTE_FLOW_ITEM_TYPE_IPV6,
+	RTE_FLOW_ITEM_TYPE_UDP,
+	RTE_FLOW_ITEM_TYPE_END,
+};
+
+enum rte_flow_item_type iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv6_tcp[] = {
+	RTE_FLOW_ITEM_TYPE_ETH,
+	RTE_FLOW_ITEM_TYPE_IPV4,
+	RTE_FLOW_ITEM_TYPE_UDP,
+	RTE_FLOW_ITEM_TYPE_L2TPV2,
+	RTE_FLOW_ITEM_TYPE_PPP,
+	RTE_FLOW_ITEM_TYPE_IPV6,
+	RTE_FLOW_ITEM_TYPE_TCP,
+	RTE_FLOW_ITEM_TYPE_END,
+};
+
+enum rte_flow_item_type iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv4[] = {
+	RTE_FLOW_ITEM_TYPE_ETH,
+	RTE_FLOW_ITEM_TYPE_IPV6,
+	RTE_FLOW_ITEM_TYPE_UDP,
+	RTE_FLOW_ITEM_TYPE_L2TPV2,
+	RTE_FLOW_ITEM_TYPE_PPP,
+	RTE_FLOW_ITEM_TYPE_IPV4,
+	RTE_FLOW_ITEM_TYPE_END,
+};
+
+enum rte_flow_item_type iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv6[] = {
+	RTE_FLOW_ITEM_TYPE_ETH,
+	RTE_FLOW_ITEM_TYPE_IPV6,
+	RTE_FLOW_ITEM_TYPE_UDP,
+	RTE_FLOW_ITEM_TYPE_L2TPV2,
+	RTE_FLOW_ITEM_TYPE_PPP,
+	RTE_FLOW_ITEM_TYPE_IPV6,
+	RTE_FLOW_ITEM_TYPE_END,
+};
+
+enum rte_flow_item_type iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv4_udp[] = {
+	RTE_FLOW_ITEM_TYPE_ETH,
+	RTE_FLOW_ITEM_TYPE_IPV6,
+	RTE_FLOW_ITEM_TYPE_UDP,
+	RTE_FLOW_ITEM_TYPE_L2TPV2,
+	RTE_FLOW_ITEM_TYPE_PPP,
+	RTE_FLOW_ITEM_TYPE_IPV4,
+	RTE_FLOW_ITEM_TYPE_UDP,
+	RTE_FLOW_ITEM_TYPE_END,
+};
+
+enum rte_flow_item_type iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv4_tcp[] = {
+	RTE_FLOW_ITEM_TYPE_ETH,
+	RTE_FLOW_ITEM_TYPE_IPV6,
+	RTE_FLOW_ITEM_TYPE_UDP,
+	RTE_FLOW_ITEM_TYPE_L2TPV2,
+	RTE_FLOW_ITEM_TYPE_PPP,
+	RTE_FLOW_ITEM_TYPE_IPV4,
+	RTE_FLOW_ITEM_TYPE_TCP,
+	RTE_FLOW_ITEM_TYPE_END,
+};
+
+enum rte_flow_item_type iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv6_udp[] = {
+	RTE_FLOW_ITEM_TYPE_ETH,
+	RTE_FLOW_ITEM_TYPE_IPV6,
+	RTE_FLOW_ITEM_TYPE_UDP,
+	RTE_FLOW_ITEM_TYPE_L2TPV2,
+	RTE_FLOW_ITEM_TYPE_PPP,
+	RTE_FLOW_ITEM_TYPE_IPV6,
+	RTE_FLOW_ITEM_TYPE_UDP,
+	RTE_FLOW_ITEM_TYPE_END,
+};
+
+enum rte_flow_item_type iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv6_tcp[] = {
+	RTE_FLOW_ITEM_TYPE_ETH,
+	RTE_FLOW_ITEM_TYPE_IPV6,
+	RTE_FLOW_ITEM_TYPE_UDP,
+	RTE_FLOW_ITEM_TYPE_L2TPV2,
+	RTE_FLOW_ITEM_TYPE_PPP,
+	RTE_FLOW_ITEM_TYPE_IPV6,
+	RTE_FLOW_ITEM_TYPE_TCP,
+	RTE_FLOW_ITEM_TYPE_END,
+};
+
+
+
 typedef struct iavf_flow_engine * (*parse_engine_t)(struct iavf_adapter *ad,
 		struct rte_flow *flow,
 		struct iavf_parser_list *parser_list,
diff --git a/drivers/net/iavf/iavf_generic_flow.h b/drivers/net/iavf/iavf_generic_flow.h
index 4794d1fb80..f2b54e1944 100644
--- a/drivers/net/iavf/iavf_generic_flow.h
+++ b/drivers/net/iavf/iavf_generic_flow.h
@@ -410,6 +410,21 @@ extern enum rte_flow_item_type iavf_pattern_eth_ipv6_gre_ipv6_tcp[];
 extern enum rte_flow_item_type iavf_pattern_eth_ipv6_gre_ipv4_udp[];
 extern enum rte_flow_item_type iavf_pattern_eth_ipv6_gre_ipv6_udp[];
 
+/* PPPoL2TPv2oUDP */
+extern enum rte_flow_item_type iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv4[];
+extern enum rte_flow_item_type iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv6[];
+extern enum rte_flow_item_type iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv4_udp[];
+extern enum rte_flow_item_type iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv4_tcp[];
+extern enum rte_flow_item_type iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv6_udp[];
+extern enum rte_flow_item_type iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv6_tcp[];
+extern enum rte_flow_item_type iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv4[];
+extern enum rte_flow_item_type iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv6[];
+extern enum rte_flow_item_type iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv4_udp[];
+extern enum rte_flow_item_type iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv4_tcp[];
+extern enum rte_flow_item_type iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv6_udp[];
+extern enum rte_flow_item_type iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv6_tcp[];
+
+
 extern const struct rte_flow_ops iavf_flow_ops;
 
 /* pattern structure */
diff --git a/drivers/net/iavf/iavf_hash.c b/drivers/net/iavf/iavf_hash.c
index 1f2d3772d1..9e7286861e 100644
--- a/drivers/net/iavf/iavf_hash.c
+++ b/drivers/net/iavf/iavf_hash.c
@@ -34,6 +34,8 @@
 /* the second IP header of GTPoGRE */
 #define IAVF_PHINT_MID_IPV4			BIT_ULL(7)
 #define IAVF_PHINT_MID_IPV6			BIT_ULL(8)
+/* L2TPV2 */
+#define IAVF_PHINT_L2TPV2			BIT_ULL(9)
 
 #define IAVF_PHINT_GTPU_MSK	(IAVF_PHINT_GTPU	| \
 				 IAVF_PHINT_GTPU_EH	| \
@@ -164,6 +166,12 @@ iavf_hash_parse_pattern_action(struct iavf_adapter *ad,
 	VIRTCHNL_PROTO_HDR_ECPRI, \
 	FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_ECPRI_PC_RTC_ID), {BUFF_NOUSED} }
 
+#define proto_hdr_l2tpv2 { \
+	VIRTCHNL_PROTO_HDR_L2TPV2, 0, {BUFF_NOUSED} }
+
+#define proto_hdr_ppp { \
+	VIRTCHNL_PROTO_HDR_PPP, 0, {BUFF_NOUSED} }
+
 #define TUNNEL_LEVEL_OUTER		0
 #define TUNNEL_LEVEL_INNER		1
 
@@ -338,6 +346,52 @@ struct virtchnl_proto_hdrs ipv4_ecpri_tmplt = {
 	TUNNEL_LEVEL_OUTER, 3, {proto_hdr_ipv4, proto_hdr_udp, proto_hdr_ecpri}
 };
 
+struct virtchnl_proto_hdrs udp_l2tpv2_ppp_ipv4_tmplt = {
+	TUNNEL_LEVEL_INNER, 3,
+	{proto_hdr_l2tpv2,
+	 proto_hdr_ppp,
+	 proto_hdr_ipv4}
+};
+
+struct virtchnl_proto_hdrs udp_l2tpv2_ppp_ipv6_tmplt = {
+	TUNNEL_LEVEL_INNER, 3,
+	{proto_hdr_l2tpv2,
+	 proto_hdr_ppp,
+	 proto_hdr_ipv6}
+};
+
+struct virtchnl_proto_hdrs udp_l2tpv2_ppp_ipv4_udp_tmplt = {
+	TUNNEL_LEVEL_INNER, 4,
+	{proto_hdr_l2tpv2,
+	 proto_hdr_ppp,
+	 proto_hdr_ipv4_with_prot,
+	 proto_hdr_udp}
+};
+
+struct virtchnl_proto_hdrs udp_l2tpv2_ppp_ipv4_tcp_tmplt = {
+	TUNNEL_LEVEL_INNER, 4,
+	{proto_hdr_l2tpv2,
+	 proto_hdr_ppp,
+	 proto_hdr_ipv4_with_prot,
+	 proto_hdr_tcp}
+};
+
+struct virtchnl_proto_hdrs udp_l2tpv2_ppp_ipv6_udp_tmplt = {
+	TUNNEL_LEVEL_INNER, 4,
+	{proto_hdr_l2tpv2,
+	 proto_hdr_ppp,
+	 proto_hdr_ipv6_with_prot,
+	 proto_hdr_udp}
+};
+
+struct virtchnl_proto_hdrs udp_l2tpv2_ppp_ipv6_tcp_tmplt = {
+	TUNNEL_LEVEL_INNER, 4,
+	{proto_hdr_l2tpv2,
+	 proto_hdr_ppp,
+	 proto_hdr_ipv6_with_prot,
+	 proto_hdr_tcp}
+};
+
 /* rss type super set */
 
 /* IPv4 outer */
@@ -493,6 +547,13 @@ static struct iavf_pattern_match_item iavf_hash_pattern_list[] = {
 	{iavf_pattern_eth_ipv6_gre_ipv4_tcp,	IAVF_RSS_TYPE_INNER_IPV4_TCP, &inner_ipv4_tcp_tmplt},
 	{iavf_pattern_eth_ipv4_gre_ipv4_udp,	IAVF_RSS_TYPE_INNER_IPV4_UDP, &inner_ipv4_udp_tmplt},
 	{iavf_pattern_eth_ipv6_gre_ipv4_udp,	IAVF_RSS_TYPE_INNER_IPV4_UDP, &inner_ipv4_udp_tmplt},
+	{iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv4,	IAVF_RSS_TYPE_INNER_IPV4,	&udp_l2tpv2_ppp_ipv4_tmplt},
+	{iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv4_udp,	IAVF_RSS_TYPE_INNER_IPV4_UDP,	&udp_l2tpv2_ppp_ipv4_udp_tmplt},
+	{iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv4_tcp,	IAVF_RSS_TYPE_INNER_IPV4_TCP,	&udp_l2tpv2_ppp_ipv4_tcp_tmplt},
+	{iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv4,	IAVF_RSS_TYPE_INNER_IPV4,	&udp_l2tpv2_ppp_ipv4_tmplt},
+	{iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv4_udp,	IAVF_RSS_TYPE_INNER_IPV4_UDP,	&udp_l2tpv2_ppp_ipv4_udp_tmplt},
+	{iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv4_tcp,	IAVF_RSS_TYPE_INNER_IPV4_TCP,	&udp_l2tpv2_ppp_ipv4_tcp_tmplt},
+
 	/* IPv6 */
 	{iavf_pattern_eth_ipv6,				IAVF_RSS_TYPE_OUTER_IPV6,	&outer_ipv6_tmplt},
 	{iavf_pattern_eth_ipv6_frag_ext,		IAVF_RSS_TYPE_OUTER_IPV6_FRAG,	&outer_ipv6_frag_tmplt},
@@ -553,6 +614,13 @@ static struct iavf_pattern_match_item iavf_hash_pattern_list[] = {
 	{iavf_pattern_eth_ipv6_gre_ipv6_tcp,	IAVF_RSS_TYPE_INNER_IPV6_TCP, &inner_ipv6_tcp_tmplt},
 	{iavf_pattern_eth_ipv4_gre_ipv6_udp,	IAVF_RSS_TYPE_INNER_IPV6_UDP, &inner_ipv6_udp_tmplt},
 	{iavf_pattern_eth_ipv6_gre_ipv6_udp,	IAVF_RSS_TYPE_INNER_IPV6_UDP, &inner_ipv6_udp_tmplt},
+	{iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv6,	IAVF_RSS_TYPE_INNER_IPV6,	&udp_l2tpv2_ppp_ipv6_tmplt},
+	{iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv6_udp,	IAVF_RSS_TYPE_INNER_IPV6_UDP,	&udp_l2tpv2_ppp_ipv6_udp_tmplt},
+	{iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv6_tcp,	IAVF_RSS_TYPE_INNER_IPV6_TCP,	&udp_l2tpv2_ppp_ipv6_tcp_tmplt},
+	{iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv6,	IAVF_RSS_TYPE_INNER_IPV6,	&udp_l2tpv2_ppp_ipv6_tmplt},
+	{iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv6_udp,	IAVF_RSS_TYPE_INNER_IPV6_UDP,	&udp_l2tpv2_ppp_ipv6_udp_tmplt},
+	{iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv6_tcp,	IAVF_RSS_TYPE_INNER_IPV6_TCP,	&udp_l2tpv2_ppp_ipv6_tcp_tmplt},
+
 };
 
 static struct iavf_flow_engine iavf_hash_engine = {
@@ -687,13 +755,17 @@ iavf_hash_parse_pattern(const struct rte_flow_item pattern[], uint64_t *phint,
 
 		switch (item->type) {
 		case RTE_FLOW_ITEM_TYPE_IPV4:
-			if (!(*phint & IAVF_PHINT_GTPU_MSK) && !(*phint & IAVF_PHINT_GRE))
+			if (!(*phint & IAVF_PHINT_GTPU_MSK) &&
+			    !(*phint & IAVF_PHINT_GRE) &&
+			    !(*phint & IAVF_PHINT_L2TPV2))
 				*phint |= IAVF_PHINT_OUTER_IPV4;
 			if ((*phint & IAVF_PHINT_GRE) && !(*phint & IAVF_PHINT_GTPU_MSK))
 				*phint |= IAVF_PHINT_MID_IPV4;
 			break;
 		case RTE_FLOW_ITEM_TYPE_IPV6:
-			if (!(*phint & IAVF_PHINT_GTPU_MSK) && !(*phint & IAVF_PHINT_GRE))
+			if (!(*phint & IAVF_PHINT_GTPU_MSK) &&
+			    !(*phint & IAVF_PHINT_GRE) &&
+			    !(*phint & IAVF_PHINT_L2TPV2))
 				*phint |= IAVF_PHINT_OUTER_IPV6;
 			if ((*phint & IAVF_PHINT_GRE) && !(*phint & IAVF_PHINT_GTPU_MSK))
 				*phint |= IAVF_PHINT_MID_IPV6;
@@ -728,6 +800,10 @@ iavf_hash_parse_pattern(const struct rte_flow_item pattern[], uint64_t *phint,
 			break;
 		case RTE_FLOW_ITEM_TYPE_GRE:
 			*phint |= IAVF_PHINT_GRE;
+			break;
+		case RTE_FLOW_ITEM_TYPE_L2TPV2:
+			*phint |= IAVF_PHINT_L2TPV2;
+			break;
 		default:
 			break;
 		}
@@ -1050,12 +1126,40 @@ iavf_refine_proto_hdrs_by_pattern(struct virtchnl_proto_hdrs *proto_hdrs,
 	proto_hdrs->tunnel_level = tun_lvl;
 }
 
+static void
+iavf_refine_proto_hdrs_l2tpv2(struct virtchnl_proto_hdrs *proto_hdrs,
+			      uint64_t phint)
+{
+	struct virtchnl_proto_hdr *hdr1;
+	int i;
+
+	if (!(phint & IAVF_PHINT_L2TPV2))
+		return;
+
+	if (proto_hdrs->tunnel_level == TUNNEL_LEVEL_INNER) {
+		/* shift headers layer */
+		for (i = proto_hdrs->count - 1 + 1; i > 0; i--)
+			proto_hdrs->proto_hdr[i] = proto_hdrs->proto_hdr[i - 1];
+
+		/* adding outer ip header at layer 0 */
+		hdr1 = &proto_hdrs->proto_hdr[0];
+		hdr1->field_selector = 0;
+		proto_hdrs->count++;
+		proto_hdrs->tunnel_level = TUNNEL_LEVEL_OUTER;
+		if (phint & IAVF_PHINT_OUTER_IPV4)
+			VIRTCHNL_SET_PROTO_HDR_TYPE(hdr1, IPV4);
+		else if (phint & IAVF_PHINT_OUTER_IPV6)
+			VIRTCHNL_SET_PROTO_HDR_TYPE(hdr1, IPV6);
+	}
+}
+
 static void iavf_refine_proto_hdrs(struct virtchnl_proto_hdrs *proto_hdrs,
 				   uint64_t rss_type, uint64_t phint)
 {
 	iavf_refine_proto_hdrs_l234(proto_hdrs, rss_type);
 	iavf_refine_proto_hdrs_by_pattern(proto_hdrs, phint);
 	iavf_refine_proto_hdrs_gtpu(proto_hdrs, rss_type);
+	iavf_refine_proto_hdrs_l2tpv2(proto_hdrs, phint);
 }
 
 static uint64_t invalid_rss_comb[] = {
-- 
2.25.1


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

* [dpdk-dev] [PATCH v4 3/3] app/testpmd: support L2TPV2 and PPP protocol pattern
  2021-10-18  9:33     ` [dpdk-dev] [PATCH v4 0/3] support PPPoL2TPv2oUDP RSS Hash Jie Wang
  2021-10-18  9:33       ` [dpdk-dev] [PATCH v4 1/3] ethdev: support PPP and L2TPV2 procotol Jie Wang
  2021-10-18  9:33       ` [dpdk-dev] [PATCH v4 2/3] net/iavf: support PPPoL2TPv2oUDP RSS Hash Jie Wang
@ 2021-10-18  9:33       ` Jie Wang
  2021-10-18 11:03         ` Ori Kam
  2021-10-19  3:08       ` [dpdk-dev] [PATCH v5 0/3] support PPPoL2TPv2oUDP RSS Hash Jie Wang
  3 siblings, 1 reply; 71+ messages in thread
From: Jie Wang @ 2021-10-18  9:33 UTC (permalink / raw)
  To: dev
  Cc: orika, ferruh.yigit, thomas, andrew.rybchenko, xiaoyun.li,
	stevex.yang, jingjing.wu, beilei.xing, wenjun1.wu, qi.z.zhang,
	Jie Wang

Add support for test-pmd to parse protocol pattern L2TPv2 and PPP.

Signed-off-by: Wenjun Wu <wenjun1.wu@intel.com>
Signed-off-by: Jie Wang <jie1x.wang@intel.com>
---
 app/test-pmd/cmdline_flow.c | 251 ++++++++++++++++++++++++++++++++++++
 1 file changed, 251 insertions(+)

diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
index a90822b660..c1046e3e28 100644
--- a/app/test-pmd/cmdline_flow.c
+++ b/app/test-pmd/cmdline_flow.c
@@ -310,6 +310,23 @@ enum index {
 	ITEM_PORT_REPRESENTOR_PORT_ID,
 	ITEM_REPRESENTED_PORT,
 	ITEM_REPRESENTED_PORT_ETHDEV_PORT_ID,
+	ITEM_L2TPV2,
+	ITEM_L2TPV2_COMMON,
+	ITEM_L2TPV2_COMMON_TYPE,
+	ITEM_L2TPV2_COMMON_TYPE_DATA_L,
+	ITEM_L2TPV2_COMMON_TYPE_CTRL,
+	ITEM_L2TPV2_MSG_DATA_L_LENGTH,
+	ITEM_L2TPV2_MSG_DATA_L_TUNNEL_ID,
+	ITEM_L2TPV2_MSG_DATA_L_SESSION_ID,
+	ITEM_L2TPV2_MSG_CTRL_LENGTH,
+	ITEM_L2TPV2_MSG_CTRL_TUNNEL_ID,
+	ITEM_L2TPV2_MSG_CTRL_SESSION_ID,
+	ITEM_L2TPV2_MSG_CTRL_NS,
+	ITEM_L2TPV2_MSG_CTRL_NR,
+	ITEM_PPP,
+	ITEM_PPP_ADDR,
+	ITEM_PPP_CTRL,
+	ITEM_PPP_PROTO_ID,
 
 	/* Validate/create actions. */
 	ACTIONS,
@@ -1018,6 +1035,8 @@ static const enum index next_item[] = {
 	ITEM_CONNTRACK,
 	ITEM_PORT_REPRESENTOR,
 	ITEM_REPRESENTED_PORT,
+	ITEM_L2TPV2,
+	ITEM_PPP,
 	END_SET,
 	ZERO,
 };
@@ -1398,6 +1417,31 @@ static const enum index item_represented_port[] = {
 	ZERO,
 };
 
+static const enum index item_l2tpv2[] = {
+	ITEM_L2TPV2_COMMON,
+	ITEM_NEXT,
+	ZERO,
+};
+
+static const enum index item_l2tpv2_common[] = {
+	ITEM_L2TPV2_COMMON_TYPE,
+	ZERO,
+};
+
+static const enum index item_l2tpv2_common_type[] = {
+	ITEM_L2TPV2_COMMON_TYPE_DATA_L,
+	ITEM_L2TPV2_COMMON_TYPE_CTRL,
+	ZERO,
+};
+
+static const enum index item_ppp[] = {
+	ITEM_PPP_ADDR,
+	ITEM_PPP_CTRL,
+	ITEM_PPP_PROTO_ID,
+	ITEM_NEXT,
+	ZERO,
+};
+
 static const enum index next_action[] = {
 	ACTION_END,
 	ACTION_VOID,
@@ -1781,6 +1825,9 @@ static int parse_vc_conf(struct context *, const struct token *,
 static int parse_vc_item_ecpri_type(struct context *, const struct token *,
 				    const char *, unsigned int,
 				    void *, unsigned int);
+static int parse_vc_item_l2tpv2_type(struct context *, const struct token *,
+				    const char *, unsigned int,
+				    void *, unsigned int);
 static int parse_vc_action_meter_color_type(struct context *,
 					const struct token *,
 					const char *, unsigned int, void *,
@@ -3682,6 +3729,153 @@ static const struct token token_list[] = {
 			     item_param),
 		.args = ARGS(ARGS_ENTRY(struct rte_flow_item_ethdev, port_id)),
 	},
+	[ITEM_L2TPV2] = {
+		.name = "l2tpv2",
+		.help = "match l2tpv2 header",
+		.priv = PRIV_ITEM(L2TPV2, sizeof(struct rte_flow_item_l2tpv2)),
+		.next = NEXT(item_l2tpv2),
+		.call = parse_vc,
+	},
+	[ITEM_L2TPV2_COMMON] = {
+		.name = "common",
+		.help = "l2tpv2 common header",
+		.next = NEXT(item_l2tpv2_common),
+	},
+	[ITEM_L2TPV2_COMMON_TYPE] = {
+		.name = "type",
+		.help = "type of common header",
+		.next = NEXT(item_l2tpv2_common_type),
+		.args = ARGS(ARG_ENTRY_HTON(struct rte_flow_item_l2tpv2)),
+	},
+	[ITEM_L2TPV2_COMMON_TYPE_DATA_L] = {
+		.name = "data_l",
+		.help = "Type #6: data message with length option",
+		.next = NEXT(NEXT_ENTRY(ITEM_L2TPV2_MSG_DATA_L_LENGTH,
+					ITEM_L2TPV2_MSG_DATA_L_TUNNEL_ID,
+					ITEM_L2TPV2_MSG_DATA_L_SESSION_ID,
+					ITEM_NEXT)),
+		.call = parse_vc_item_l2tpv2_type,
+	},
+	[ITEM_L2TPV2_MSG_DATA_L_LENGTH] = {
+		.name = "length",
+		.help = "message length",
+		.next = NEXT(NEXT_ENTRY(ITEM_L2TPV2_MSG_DATA_L_LENGTH,
+					ITEM_L2TPV2_COMMON, ITEM_NEXT),
+			     NEXT_ENTRY(COMMON_UNSIGNED),
+			     item_param),
+		.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2,
+					     hdr.type6.length)),
+	},
+	[ITEM_L2TPV2_MSG_DATA_L_TUNNEL_ID] = {
+		.name = "tunnel_id",
+		.help = "tunnel identifier",
+		.next = NEXT(NEXT_ENTRY(ITEM_L2TPV2_MSG_DATA_L_TUNNEL_ID,
+					ITEM_L2TPV2_COMMON, ITEM_NEXT),
+			     NEXT_ENTRY(COMMON_UNSIGNED),
+			     item_param),
+		.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2,
+					     hdr.type6.tunnel_id)),
+	},
+	[ITEM_L2TPV2_MSG_DATA_L_SESSION_ID] = {
+		.name = "session_id",
+		.help = "session identifier",
+		.next = NEXT(NEXT_ENTRY(ITEM_L2TPV2_MSG_DATA_L_SESSION_ID,
+					ITEM_L2TPV2_COMMON, ITEM_NEXT),
+			     NEXT_ENTRY(COMMON_UNSIGNED),
+			     item_param),
+		.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2,
+					     hdr.type6.session_id)),
+	},
+	[ITEM_L2TPV2_COMMON_TYPE_CTRL] = {
+		.name = "control",
+		.help = "Type #3: conrtol message contains length, ns, nr options",
+		.next = NEXT(NEXT_ENTRY(ITEM_L2TPV2_MSG_CTRL_LENGTH,
+					ITEM_L2TPV2_MSG_CTRL_TUNNEL_ID,
+					ITEM_L2TPV2_MSG_CTRL_SESSION_ID,
+					ITEM_L2TPV2_MSG_CTRL_NS,
+					ITEM_L2TPV2_MSG_CTRL_NR,
+					ITEM_NEXT)),
+		.call = parse_vc_item_l2tpv2_type,
+	},
+	[ITEM_L2TPV2_MSG_CTRL_LENGTH] = {
+		.name = "length",
+		.help = "message length",
+		.next = NEXT(NEXT_ENTRY(ITEM_L2TPV2_MSG_CTRL_LENGTH,
+					ITEM_L2TPV2_COMMON, ITEM_NEXT),
+			     NEXT_ENTRY(COMMON_UNSIGNED),
+			     item_param),
+		.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2,
+					     hdr.type3.length)),
+	},
+	[ITEM_L2TPV2_MSG_CTRL_TUNNEL_ID] = {
+		.name = "tunnel_id",
+		.help = "tunnel identifier",
+		.next = NEXT(NEXT_ENTRY(ITEM_L2TPV2_MSG_CTRL_TUNNEL_ID,
+					ITEM_L2TPV2_COMMON, ITEM_NEXT),
+			     NEXT_ENTRY(COMMON_UNSIGNED),
+			     item_param),
+		.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2,
+					     hdr.type3.tunnel_id)),
+	},
+	[ITEM_L2TPV2_MSG_CTRL_SESSION_ID] = {
+		.name = "session_id",
+		.help = "session identifier",
+		.next = NEXT(NEXT_ENTRY(ITEM_L2TPV2_MSG_CTRL_SESSION_ID,
+					ITEM_L2TPV2_COMMON, ITEM_NEXT),
+			     NEXT_ENTRY(COMMON_UNSIGNED),
+			     item_param),
+		.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2,
+					     hdr.type3.session_id)),
+	},
+	[ITEM_L2TPV2_MSG_CTRL_NS] = {
+		.name = "ns",
+		.help = "sequence number for message",
+		.next = NEXT(NEXT_ENTRY(ITEM_L2TPV2_MSG_CTRL_NS,
+					ITEM_L2TPV2_COMMON, ITEM_NEXT),
+			     NEXT_ENTRY(COMMON_UNSIGNED),
+			     item_param),
+		.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2,
+					     hdr.type3.ns)),
+	},
+	[ITEM_L2TPV2_MSG_CTRL_NR] = {
+		.name = "nr",
+		.help = "sequence number for next receive message",
+		.next = NEXT(NEXT_ENTRY(ITEM_L2TPV2_MSG_CTRL_NS,
+					ITEM_L2TPV2_COMMON, ITEM_NEXT),
+			     NEXT_ENTRY(COMMON_UNSIGNED),
+			     item_param),
+		.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2,
+					     hdr.type3.nr)),
+	},
+	[ITEM_PPP] = {
+		.name = "ppp",
+		.help = "match ppp header",
+		.priv = PRIV_ITEM(PPP, sizeof(struct rte_flow_item_ppp)),
+		.next = NEXT(item_ppp),
+		.call = parse_vc,
+	},
+	[ITEM_PPP_ADDR] = {
+		.name = "addr",
+		.help = "ppp address",
+		.next = NEXT(item_ppp, NEXT_ENTRY(COMMON_UNSIGNED),
+			     item_param),
+		.args = ARGS(ARGS_ENTRY(struct rte_flow_item_ppp, hdr.addr)),
+	},
+	[ITEM_PPP_CTRL] = {
+		.name = "ctrl",
+		.help = "ppp control",
+		.next = NEXT(item_ppp, NEXT_ENTRY(COMMON_UNSIGNED),
+			     item_param),
+		.args = ARGS(ARGS_ENTRY(struct rte_flow_item_ppp, hdr.ctrl)),
+	},
+	[ITEM_PPP_PROTO_ID] = {
+		.name = "proto_id",
+		.help = "ppp protocol id",
+		.next = NEXT(item_ppp, NEXT_ENTRY(COMMON_UNSIGNED),
+			     item_param),
+		.args = ARGS(ARGS_ENTRY(struct rte_flow_item_ppp,
+					hdr.proto_id)),
+	},
 	/* Validate/create actions. */
 	[ACTIONS] = {
 		.name = "actions",
@@ -5569,6 +5763,57 @@ parse_vc_item_ecpri_type(struct context *ctx, const struct token *token,
 	return len;
 }
 
+/** Parse L2TPV2 common header type field. */
+static int
+parse_vc_item_l2tpv2_type(struct context *ctx, const struct token *token,
+			 const char *str, unsigned int len,
+			 void *buf, unsigned int size)
+{
+	struct rte_flow_item_l2tpv2 *l2tpv2;
+	struct rte_flow_item_l2tpv2 *l2tpv2_mask;
+	struct rte_flow_item *item;
+	uint32_t data_size;
+	uint8_t msg_type = 0;
+	struct buffer *out = buf;
+	const struct arg *arg;
+
+	(void)size;
+	/* Token name must match. */
+	if (parse_default(ctx, token, str, len, NULL, 0) < 0)
+		return -1;
+	switch (ctx->curr) {
+	case ITEM_L2TPV2_COMMON_TYPE_DATA_L:
+		msg_type |= 0x4000;
+		break;
+	case ITEM_L2TPV2_COMMON_TYPE_CTRL:
+		msg_type |= 0xC800;
+		break;
+	default:
+		return -1;
+	}
+	if (!ctx->object)
+		return len;
+	arg = pop_args(ctx);
+	if (!arg)
+		return -1;
+	l2tpv2 = (struct rte_flow_item_l2tpv2 *)out->args.vc.data;
+	l2tpv2->hdr.common.flags_version |= msg_type;
+	data_size = ctx->objdata / 3; /* spec, last, mask */
+	l2tpv2_mask = (struct rte_flow_item_l2tpv2 *)(out->args.vc.data +
+						    (data_size * 2));
+	l2tpv2_mask->hdr.common.flags_version = 0xFFFF;
+	if (arg->hton) {
+		l2tpv2->hdr.common.flags_version =
+			rte_cpu_to_be_16(l2tpv2->hdr.common.flags_version);
+		l2tpv2_mask->hdr.common.flags_version =
+		    rte_cpu_to_be_16(l2tpv2_mask->hdr.common.flags_version);
+	}
+	item = &out->args.vc.pattern[out->args.vc.pattern_n - 1];
+	item->spec = l2tpv2;
+	item->mask = l2tpv2_mask;
+	return len;
+}
+
 /** Parse meter color action type. */
 static int
 parse_vc_action_meter_color_type(struct context *ctx, const struct token *token,
@@ -8461,6 +8706,12 @@ flow_item_default_mask(const struct rte_flow_item *item)
 	case RTE_FLOW_ITEM_TYPE_REPRESENTED_PORT:
 		mask = &rte_flow_item_ethdev_mask;
 		break;
+	case RTE_FLOW_ITEM_TYPE_L2TPV2:
+		mask = &rte_flow_item_l2tpv2_mask;
+		break;
+	case RTE_FLOW_ITEM_TYPE_PPP:
+		mask = &rte_flow_item_ppp_mask;
+		break;
 	default:
 		break;
 	}
-- 
2.25.1


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

* Re: [dpdk-dev] [PATCH v4 1/3] ethdev: support PPP and L2TPV2 procotol
  2021-10-18  9:33       ` [dpdk-dev] [PATCH v4 1/3] ethdev: support PPP and L2TPV2 procotol Jie Wang
@ 2021-10-18 10:56         ` Ori Kam
  2021-10-18 12:39           ` Zhang, Qi Z
  0 siblings, 1 reply; 71+ messages in thread
From: Ori Kam @ 2021-10-18 10:56 UTC (permalink / raw)
  To: Jie Wang, dev
  Cc: ferruh.yigit, NBU-Contact-Thomas Monjalon, andrew.rybchenko,
	xiaoyun.li, stevex.yang, jingjing.wu, beilei.xing, wenjun1.wu,
	qi.z.zhang

Hi Jie,

I realy don't know why you keep insisting about the RSS?
you keep using it in the documentation, the reason I care is that
you are not doing anything with RSS, and you can't have RSS on the PPP or
L2TPV2 fields right?

> -----Original Message-----
> From: Jie Wang <jie1x.wang@intel.com>
> Sent: Monday, October 18, 2021 12:34 PM
> To: dev@dpdk.org
> Subject: [PATCH v4 1/3] ethdev: support PPP and L2TPV2 procotol
> 
> Added flow pattern items and header formats of L2TPv2 and PPP.
> 
> Signed-off-by: Wenjun Wu <wenjun1.wu@intel.com>
> Signed-off-by: Jie Wang <jie1x.wang@intel.com>
> ---
>  doc/guides/prog_guide/rte_flow.rst     |  25 +++
>  doc/guides/rel_notes/release_21_11.rst |   5 +
>  lib/ethdev/rte_flow.c                  |   2 +
>  lib/ethdev/rte_flow.h                  |  66 ++++++++
>  lib/net/rte_l2tpv2.h                   | 214 +++++++++++++++++++++++++
>  lib/net/rte_ppp.h                      |  35 ++++
>  6 files changed, 347 insertions(+)
>  create mode 100644 lib/net/rte_l2tpv2.h  create mode 100644 lib/net/rte_ppp.h
> 
> diff --git a/doc/guides/prog_guide/rte_flow.rst b/doc/guides/prog_guide/rte_flow.rst
> index fa05fe0845..6277c641ef 100644
> --- a/doc/guides/prog_guide/rte_flow.rst
> +++ b/doc/guides/prog_guide/rte_flow.rst
> @@ -1548,6 +1548,31 @@ This item is meant to use the same structure as `Item:
> PORT_REPRESENTOR`_.
> 
>  See also `Action: REPRESENTED_PORT`_.
> 
> +Item: ``L2TPV2``
> +^^^^^^^^^^^^^^^^^^^
> +
> +Matches a L2TPv2 header.
> +
> +- ``flags_version``: flags(12b), version(4b).
> +- ``length``: total length of the message.
> +- ``tunnel_id``: identifier for the control connection.
> +- ``session_id``: identifier for a session within a tunnel.
> +- ``ns``: sequence number for this date or control message.
> +- ``nr``: sequence number expected in the next control message to be received.
> +- ``offset_size``: offset of payload data.
> +- ``offset_padding``: offset padding, variable length.
> +- Default ``mask`` matches flags_version only.
> +
> +Item: ``PPP``
> +^^^^^^^^^^^^^^^^^^^
> +
> +Matches a PPP header.
> +
> +- ``addr``: ppp address.
> +- ``ctrl``: ppp control.
> +- ``proto_id``: ppp protocol identifier.
> +- Default ``mask`` matches addr, ctrl, proto_id.
> +
>  Actions
>  ~~~~~~~
> 
> diff --git a/doc/guides/rel_notes/release_21_11.rst b/doc/guides/rel_notes/release_21_11.rst
> index ec2a788789..e1b23ce0e9 100644
> --- a/doc/guides/rel_notes/release_21_11.rst
> +++ b/doc/guides/rel_notes/release_21_11.rst
> @@ -98,6 +98,11 @@ New Features
> 
>    Added an ethdev API which can help users get device configuration.
> 
> +* **Added L2TPV2 and PPP protocol support in rte_flow.**
> +
> +  Added flow pattern items and header formats of L2TPv2 and PPP to
> + support  PPP over L2TPv2 over UDP protocol RSS Hash.

Why RSS hash appears here?

> +
>  * **Updated AF_XDP PMD.**
> 
>    * Disabled secondary process support.
> diff --git a/lib/ethdev/rte_flow.c b/lib/ethdev/rte_flow.c index 29f2b0e954..0bfbeb73e8 100644
> --- a/lib/ethdev/rte_flow.c
> +++ b/lib/ethdev/rte_flow.c
> @@ -102,6 +102,8 @@ static const struct rte_flow_desc_data rte_flow_desc_item[] = {
>  	MK_FLOW_ITEM(CONNTRACK, sizeof(uint32_t)),
>  	MK_FLOW_ITEM(PORT_REPRESENTOR, sizeof(struct rte_flow_item_ethdev)),
>  	MK_FLOW_ITEM(REPRESENTED_PORT, sizeof(struct rte_flow_item_ethdev)),
> +	MK_FLOW_ITEM(L2TPV2, sizeof(struct rte_flow_item_l2tpv2)),
> +	MK_FLOW_ITEM(PPP, sizeof(struct rte_flow_item_ppp)),
>  };
> 
>  /** Generate flow_action[] entry. */
> diff --git a/lib/ethdev/rte_flow.h b/lib/ethdev/rte_flow.h index d5bfdaaaf2..2bc825b567 100644
> --- a/lib/ethdev/rte_flow.h
> +++ b/lib/ethdev/rte_flow.h
> @@ -35,6 +35,8 @@
>  #include <rte_mbuf_dyn.h>
>  #include <rte_meter.h>
>  #include <rte_gtp.h>
> +#include <rte_l2tpv2.h>
> +#include <rte_ppp.h>
> 
>  #ifdef __cplusplus
>  extern "C" {
> @@ -635,6 +637,21 @@ enum rte_flow_item_type {
>  	 * @see struct rte_flow_item_ethdev
>  	 */
>  	RTE_FLOW_ITEM_TYPE_REPRESENTED_PORT,
> +
> +	/**
> +	 * Matches L2TPV2 Header.
> +	 *
> +	 * See struct rte_flow_item_l2tpv2.
> +	 */
> +	RTE_FLOW_ITEM_TYPE_L2TPV2,
> +
> +	/**
> +	 * Matches PPP Header.
> +	 *
> +	 * See struct rte_flow_item_ppp.
> +	 */
> +	RTE_FLOW_ITEM_TYPE_PPP,
> +
>  };
> 
>  /**
> @@ -1891,6 +1908,55 @@ static const struct rte_flow_item_ethdev rte_flow_item_ethdev_mask = {
> };  #endif
> 
> +/**
> + * @warning
> + * @b EXPERIMENTAL: this structure may change without prior notice
> + * RTE_FLOW_ITEM_TYPE_L2TPV2
> + *
> + * Matches L2TPv2 Header
> + */
> +struct rte_flow_item_l2tpv2 {
> +	struct rte_l2tpv2_combined_msg_hdr hdr; };
> +
> +/** Default mask for RTE_FLOW_ITEM_TYPE_L2TPV2. */ #ifndef __cplusplus
> +static const struct rte_flow_item_l2tpv2 rte_flow_item_l2tpv2_mask = {
> +	/*
> +	 * flags and version bit mask
> +	 * 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0
> +	 * T L x x S x O P x x x x V V V V
> +	 */
> +	.hdr = {
> +		.common = {
> +			.flags_version = 0xcb0f,
> +		},
> +	},
> +};
> +#endif
> +
> +/**
> + * @warning
> + * @b EXPERIMENTAL: this structure may change without prior notice
> + * RTE_FLOW_ITEM_TYPE_PPP
> + *
> + * Matches PPP Header
> + */
> +struct rte_flow_item_ppp {
> +	struct rte_ppp_hdr hdr;
> +};
> +
> +/** Default mask for RTE_FLOW_ITEM_TYPE_PPP. */ #ifndef __cplusplus
> +static const struct rte_flow_item_ppp rte_flow_item_ppp_mask = {
> +	.hdr = {
> +		.addr = 0xff,
> +		.ctrl = 0xff,
> +		.proto_id = 0xffff,
> +	}
> +};
> +#endif
> +
>  /**
>   * Matching pattern item definition.
>   *
> diff --git a/lib/net/rte_l2tpv2.h b/lib/net/rte_l2tpv2.h new file mode 100644 index
> 0000000000..aea3c689be
> --- /dev/null
> +++ b/lib/net/rte_l2tpv2.h
> @@ -0,0 +1,214 @@
> +/* SPDX-License-Identifier: BSD-3-Clause
> + * Copyright 2021 Mellanox Technologies, Ltd  */
> +
> +#ifndef _RTE_L2TPV2_H_
> +#define _RTE_L2TPV2_H_
> +
> +/**
> + * @file
> + *
> + * L2TP header:
> + *  0                   1                   2                   3
> + *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
> + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
> + * |T|L|x|x|S|x|O|P|x|x|x|x|  Ver  |          Length (opt)         |
> + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
> + * |           Tunnel ID           |           Session ID          |
> + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
> + * |             Ns (opt)          |             Nr (opt)          |
> + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
> + * |      Offset Size (opt)        |    Offset pad... (opt)
> + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
> + *
> + * The Type (T) bit indicates the type of message. It is set to 0 for a
> +data
> + * message and 1 for a control message.
> + *
> + * If the Length (L) bit is 1, the Length field is present. This bit
> +MUST be
> + * set to 1 for control messages.
> + *
> + * The x bits are reserved for future extensions. All reserved bits
> +MUST
> + * be set to 0 on outgoing messages and ignored on incoming messages.
> + *
> + * If the Sequence (S) bit is set to 1 the Ns and Nr fields are present.
> + * The S bit MUST be set to 1 for control messages.
> + *
> + * If the Offset (O) bit is 1, the Offset Size field is present. The O
> + * bit MUST be set to 0 for control messages.
> + *
> + * If the Priority (P) bit is 1, this data message should receive
> + * preferential treatment in its local queuing and transmission.
> + * The P bit MUST be set to 0 for control messages.
> + *
> + * Ver MUST be 2, indicating the version of the L2TP data message header.
> + *
> + * The Length field indicates the total length of the message in octets.
> + *
> + * Tunnel ID indicates the identifier for the control connection.
> + *
> + * Session ID indicates the identifier for a session within a tunnel.
> + *
> + * Ns indicates the sequence number for this data or control message.
> + *
> + * Nr indicates the sequence number expected in the next control
> +message
> + * to be received.
> + *
> + * The Offset Size field, if present, specifies the number of octets
> + * past the L2TP header at which the payload data is expected to start.
> + * Actual data within the offset padding is undefined. If the offset
> + * field is present, the L2TP header ends after the last octet of the
> + * offset padding.
> + */
> +
> +#include <stdint.h>
> +#include <rte_byteorder.h>
> +
> +#ifdef __cplusplus
> +extern "C" {
> +#endif
> +
> +/**
> + * L2TPv2 Common Header
> + */
> +RTE_STD_C11
> +struct rte_l2tpv2_common_hdr {
> +	union {
> +		rte_be16_t flags_version;
> +		struct {
> +#if RTE_BYTE_ORDER == RTE_LITTLE_ENDIAN
> +			rte_be16_t t:1;		/**< message Type */
> +			rte_be16_t l:1;		/**< length option bit*/
> +			rte_be16_t res1:2;	/**< reserved */
> +			rte_be16_t s:1;		/**< ns/nr option bit*/
> +			rte_be16_t res2:1;	/**< reserved */
> +			rte_be16_t o:1;		/**< offset option bit*/
> +			rte_be16_t p:1;		/**< priority option bit*/
> +			rte_be16_t res3:4;	/**< reserved */
> +			rte_be16_t ver:4;	/**< protocol version */
> +#elif RTE_BYTE_ORDER == RTE_BIG_ENDIAN
> +			rte_be16_t ver:4;	/**< protocol version */
> +			rte_be16_t res3:4;	/**< reserved */
> +			rte_be16_t p:1;		/**< priority option bit*/
> +			rte_be16_t o:1;		/**< offset option bit*/
> +			rte_be16_t res2:1;	/**< reserved */
> +			rte_be16_t s:1;		/**< ns/nr option bit*/
> +			rte_be16_t res1:2;	/**< reserved */
> +			rte_be16_t l:1;		/**< length option bit*/
> +			rte_be16_t t:1;		/**< message Type */
> +#endif
> +		};
> +	};
> +};
> +
> +/*
> + * L2TPv2 message Header contains all options(length, ns, nr,
> + * offset size, offset padding).
> + */
> +struct rte_l2tpv2_msg_with_all_options {
> +	rte_be16_t length;		/**< length(16) */
> +	rte_be16_t tunnel_id;		/**< tunnel id(16) */
> +	rte_be16_t session_id;		/**< session id(16) */
> +	rte_be16_t ns;			/**< Ns(16) */
> +	rte_be16_t nr;			/**< Nr(16) */
> +	rte_be16_t offset_size;		/**< offset size(16) */
> +	uint8_t   *offset_padding;	/**< offset padding(variable length) */
> +};
> +
> +/*
> + * L2TPv2 message Header contains all options except length(ns, nr,
> + * offset size, offset padding).
> + */
> +struct rte_l2tpv2_msg_without_length {
> +	rte_be16_t tunnel_id;		/**< tunnel id(16) */
> +	rte_be16_t session_id;		/**< session id(16) */
> +	rte_be16_t ns;			/**< Ns(16) */
> +	rte_be16_t nr;			/**< Nr(16) */
> +	rte_be16_t offset_size;		/**< offset size(16) */
> +	uint8_t   *offset_padding;	/**< offset padding(variable length) */
> +};
> +
> +/*
> + * L2TPv2 message Header contains all options except ns_nr(length,
> + * offset size, offset padding).
> + * Ns and Nr MUST be toghter.
> + */
> +struct rte_l2tpv2_msg_without_ns_nr {
> +	rte_be16_t length;		/**< length(16) */
> +	rte_be16_t tunnel_id;		/**< tunnel id(16) */
> +	rte_be16_t session_id;		/**< session id(16) */
> +	rte_be16_t offset_size;		/**< offset size(16) */
> +	uint8_t   *offset_padding;	/**< offset padding(variable length) */
> +};
> +
> +/*
> + * L2TPv2 message Header contains all options except ns_nr(length, ns, nr).
> + * offset size and offset padding MUST be toghter.
> + */
> +struct rte_l2tpv2_msg_without_offset {
> +	rte_be16_t length;		/**< length(16) */
> +	rte_be16_t tunnel_id;		/**< tunnel id(16) */
> +	rte_be16_t session_id;		/**< session id(16) */
> +	rte_be16_t ns;			/**< Ns(16) */
> +	rte_be16_t nr;			/**< Nr(16) */
> +};
> +
> +/*
> + * L2TPv2 message Header contains options offset size and offset padding.
> + */
> +struct rte_l2tpv2_msg_with_offset {
> +	rte_be16_t tunnel_id;		/**< tunnel id(16) */
> +	rte_be16_t session_id;		/**< session id(16) */
> +	rte_be16_t offset_size;		/**< offset size(16) */
> +	uint8_t   *offset_padding;	/**< offset padding(variable length) */
> +};
> +
> +/*
> + * L2TPv2 message Header contains options ns and nr.
> + */
> +struct rte_l2tpv2_msg_with_ns_nr {
> +	rte_be16_t tunnel_id;		/**< tunnel id(16) */
> +	rte_be16_t session_id;		/**< session id(16) */
> +	rte_be16_t ns;			/**< Ns(16) */
> +	rte_be16_t nr;			/**< Nr(16) */
> +};
> +
> +/*
> + * L2TPv2 message Header contains option length.
> + */
> +struct rte_l2tpv2_msg_with_length {
> +	rte_be16_t length;		/**< length(16) */
> +	rte_be16_t tunnel_id;		/**< tunnel id(16) */
> +	rte_be16_t session_id;		/**< session id(16) */
> +};
> +
> +/*
> + * L2TPv2 message Header without all options.
> + */
> +struct rte_l2tpv2_msg_without_all_options {
> +	rte_be16_t tunnel_id;		/**< tunnel id(16) */
> +	rte_be16_t session_id;		/**< session id(16) */
> +};
> +
> +/**
> + * L2TPv2 Combined Message Header Format: Common Header + Options  */
> +RTE_STD_C11
> +struct rte_l2tpv2_combined_msg_hdr {
> +	struct rte_l2tpv2_common_hdr common;
> +	union {
> +		struct rte_l2tpv2_msg_with_all_options type0;
> +		struct rte_l2tpv2_msg_without_length type1;
> +		struct rte_l2tpv2_msg_without_ns_nr type2;
> +		struct rte_l2tpv2_msg_without_offset type3;
> +		struct rte_l2tpv2_msg_with_offset type4;
> +		struct rte_l2tpv2_msg_with_ns_nr type5;
> +		struct rte_l2tpv2_msg_with_length type6;
> +		struct rte_l2tpv2_msg_without_all_options type7;
> +	};
> +};
> +
> +#ifdef __cplusplus
> +}
> +#endif
> +
> +#endif /* _RTE_L2TPV2_H_ */
> diff --git a/lib/net/rte_ppp.h b/lib/net/rte_ppp.h new file mode 100644 index
> 0000000000..9ea633baa7
> --- /dev/null
> +++ b/lib/net/rte_ppp.h
> @@ -0,0 +1,35 @@
> +/* SPDX-License-Identifier: BSD-3-Clause
> + * Copyright 2021 Mellanox Technologies, Ltd  */
> +
> +#ifndef _RTE_PPP_H_
> +#define _RTE_PPP_H_
> +
> +/**
> + * @file
> + *
> + * PPP headers definition.
> + *
> + */
> +
> +#include <stdint.h>
> +#include <rte_byteorder.h>
> +
> +#ifdef __cplusplus
> +extern "C" {
> +#endif
> +
> +/**
> + * PPP Header
> + */
> +struct rte_ppp_hdr {
> +	uint8_t addr; /**< ppp address(8) */
> +	uint8_t ctrl; /**< ppp control(8) */
> +	rte_be16_t proto_id; /**< ppp protocol id(16) */ } __rte_packed;
> +
> +#ifdef __cplusplus
> +}
> +#endif
> +
> +#endif /* _RTE_PPP_H_ */
> --
> 2.25.1

Best,
Ori

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

* Re: [dpdk-dev] [PATCH v4 3/3] app/testpmd: support L2TPV2 and PPP protocol pattern
  2021-10-18  9:33       ` [dpdk-dev] [PATCH v4 3/3] app/testpmd: support L2TPV2 and PPP protocol pattern Jie Wang
@ 2021-10-18 11:03         ` Ori Kam
  2021-10-18 12:41           ` Zhang, Qi Z
  0 siblings, 1 reply; 71+ messages in thread
From: Ori Kam @ 2021-10-18 11:03 UTC (permalink / raw)
  To: Jie Wang, dev
  Cc: ferruh.yigit, NBU-Contact-Thomas Monjalon, andrew.rybchenko,
	xiaoyun.li, stevex.yang, jingjing.wu, beilei.xing, wenjun1.wu,
	qi.z.zhang

Hi Jie,


> -----Original Message-----
> From: Jie Wang <jie1x.wang@intel.com>
> Sent: Monday, October 18, 2021 12:34 PM
> To: dev@dpdk.org
> Subject: [PATCH v4 3/3] app/testpmd: support L2TPV2 and PPP protocol pattern
> 
> Add support for test-pmd to parse protocol pattern L2TPv2 and PPP.
> 
> Signed-off-by: Wenjun Wu <wenjun1.wu@intel.com>
> Signed-off-by: Jie Wang <jie1x.wang@intel.com>
> ---



>  app/test-pmd/cmdline_flow.c | 251 ++++++++++++++++++++++++++++++++++++
>  1 file changed, 251 insertions(+)
> 
> diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c index
> a90822b660..c1046e3e28 100644
> --- a/app/test-pmd/cmdline_flow.c
> +++ b/app/test-pmd/cmdline_flow.c
> @@ -310,6 +310,23 @@ enum index {
>  	ITEM_PORT_REPRESENTOR_PORT_ID,
>  	ITEM_REPRESENTED_PORT,
>  	ITEM_REPRESENTED_PORT_ETHDEV_PORT_ID,
> +	ITEM_L2TPV2,
> +	ITEM_L2TPV2_COMMON,
> +	ITEM_L2TPV2_COMMON_TYPE,
> +	ITEM_L2TPV2_COMMON_TYPE_DATA_L,
> +	ITEM_L2TPV2_COMMON_TYPE_CTRL,
> +	ITEM_L2TPV2_MSG_DATA_L_LENGTH,
> +	ITEM_L2TPV2_MSG_DATA_L_TUNNEL_ID,
> +	ITEM_L2TPV2_MSG_DATA_L_SESSION_ID,
> +	ITEM_L2TPV2_MSG_CTRL_LENGTH,
> +	ITEM_L2TPV2_MSG_CTRL_TUNNEL_ID,
> +	ITEM_L2TPV2_MSG_CTRL_SESSION_ID,
> +	ITEM_L2TPV2_MSG_CTRL_NS,
> +	ITEM_L2TPV2_MSG_CTRL_NR,
> +	ITEM_PPP,
> +	ITEM_PPP_ADDR,
> +	ITEM_PPP_CTRL,
> +	ITEM_PPP_PROTO_ID,
> 
>  	/* Validate/create actions. */
>  	ACTIONS,
> @@ -1018,6 +1035,8 @@ static const enum index next_item[] = {
>  	ITEM_CONNTRACK,
>  	ITEM_PORT_REPRESENTOR,
>  	ITEM_REPRESENTED_PORT,
> +	ITEM_L2TPV2,
> +	ITEM_PPP,
>  	END_SET,
>  	ZERO,
>  };
> @@ -1398,6 +1417,31 @@ static const enum index item_represented_port[] = {
>  	ZERO,
>  };
> 
> +static const enum index item_l2tpv2[] = {
> +	ITEM_L2TPV2_COMMON,
> +	ITEM_NEXT,
> +	ZERO,
> +};
> +
> +static const enum index item_l2tpv2_common[] = {
> +	ITEM_L2TPV2_COMMON_TYPE,
> +	ZERO,
> +};
> +
> +static const enum index item_l2tpv2_common_type[] = {
> +	ITEM_L2TPV2_COMMON_TYPE_DATA_L,
> +	ITEM_L2TPV2_COMMON_TYPE_CTRL,
> +	ZERO,
> +};
> +
> +static const enum index item_ppp[] = {
> +	ITEM_PPP_ADDR,
> +	ITEM_PPP_CTRL,
> +	ITEM_PPP_PROTO_ID,
> +	ITEM_NEXT,
> +	ZERO,
> +};
> +
>  static const enum index next_action[] = {
>  	ACTION_END,
>  	ACTION_VOID,
> @@ -1781,6 +1825,9 @@ static int parse_vc_conf(struct context *, const struct token *,  static int
> parse_vc_item_ecpri_type(struct context *, const struct token *,
>  				    const char *, unsigned int,
>  				    void *, unsigned int);
> +static int parse_vc_item_l2tpv2_type(struct context *, const struct token *,
> +				    const char *, unsigned int,
> +				    void *, unsigned int);
>  static int parse_vc_action_meter_color_type(struct context *,
>  					const struct token *,
>  					const char *, unsigned int, void *, @@ -3682,6 +3729,153 @@
> static const struct token token_list[] = {
>  			     item_param),
>  		.args = ARGS(ARGS_ENTRY(struct rte_flow_item_ethdev, port_id)),
>  	},
> +	[ITEM_L2TPV2] = {
> +		.name = "l2tpv2",
> +		.help = "match l2tpv2 header",
> +		.priv = PRIV_ITEM(L2TPV2, sizeof(struct rte_flow_item_l2tpv2)),
> +		.next = NEXT(item_l2tpv2),
> +		.call = parse_vc,
> +	},
> +	[ITEM_L2TPV2_COMMON] = {
> +		.name = "common",
> +		.help = "l2tpv2 common header",
> +		.next = NEXT(item_l2tpv2_common),
> +	},
> +	[ITEM_L2TPV2_COMMON_TYPE] = {
> +		.name = "type",
> +		.help = "type of common header",
> +		.next = NEXT(item_l2tpv2_common_type),
> +		.args = ARGS(ARG_ENTRY_HTON(struct rte_flow_item_l2tpv2)),
> +	},
> +	[ITEM_L2TPV2_COMMON_TYPE_DATA_L] = {
> +		.name = "data_l",
> +		.help = "Type #6: data message with length option",
> +		.next = NEXT(NEXT_ENTRY(ITEM_L2TPV2_MSG_DATA_L_LENGTH,
> +					ITEM_L2TPV2_MSG_DATA_L_TUNNEL_ID,
> +					ITEM_L2TPV2_MSG_DATA_L_SESSION_ID,
> +					ITEM_NEXT)),
> +		.call = parse_vc_item_l2tpv2_type,
> +	},
> +	[ITEM_L2TPV2_MSG_DATA_L_LENGTH] = {
> +		.name = "length",
> +		.help = "message length",
> +		.next = NEXT(NEXT_ENTRY(ITEM_L2TPV2_MSG_DATA_L_LENGTH,
> +					ITEM_L2TPV2_COMMON, ITEM_NEXT),
> +			     NEXT_ENTRY(COMMON_UNSIGNED),
> +			     item_param),
> +		.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2,
> +					     hdr.type6.length)),
> +	},
> +	[ITEM_L2TPV2_MSG_DATA_L_TUNNEL_ID] = {
> +		.name = "tunnel_id",
> +		.help = "tunnel identifier",
> +		.next = NEXT(NEXT_ENTRY(ITEM_L2TPV2_MSG_DATA_L_TUNNEL_ID,
> +					ITEM_L2TPV2_COMMON, ITEM_NEXT),
> +			     NEXT_ENTRY(COMMON_UNSIGNED),
> +			     item_param),
> +		.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2,
> +					     hdr.type6.tunnel_id)),
> +	},
> +	[ITEM_L2TPV2_MSG_DATA_L_SESSION_ID] = {
> +		.name = "session_id",
> +		.help = "session identifier",
> +		.next = NEXT(NEXT_ENTRY(ITEM_L2TPV2_MSG_DATA_L_SESSION_ID,
> +					ITEM_L2TPV2_COMMON, ITEM_NEXT),
> +			     NEXT_ENTRY(COMMON_UNSIGNED),
> +			     item_param),
> +		.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2,
> +					     hdr.type6.session_id)),
> +	},
> +	[ITEM_L2TPV2_COMMON_TYPE_CTRL] = {
> +		.name = "control",
> +		.help = "Type #3: conrtol message contains length, ns, nr options",
> +		.next = NEXT(NEXT_ENTRY(ITEM_L2TPV2_MSG_CTRL_LENGTH,
> +					ITEM_L2TPV2_MSG_CTRL_TUNNEL_ID,
> +					ITEM_L2TPV2_MSG_CTRL_SESSION_ID,
> +					ITEM_L2TPV2_MSG_CTRL_NS,
> +					ITEM_L2TPV2_MSG_CTRL_NR,
> +					ITEM_NEXT)),
> +		.call = parse_vc_item_l2tpv2_type,
> +	},
> +	[ITEM_L2TPV2_MSG_CTRL_LENGTH] = {
> +		.name = "length",
> +		.help = "message length",
> +		.next = NEXT(NEXT_ENTRY(ITEM_L2TPV2_MSG_CTRL_LENGTH,
> +					ITEM_L2TPV2_COMMON, ITEM_NEXT),
> +			     NEXT_ENTRY(COMMON_UNSIGNED),
> +			     item_param),
> +		.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2,
> +					     hdr.type3.length)),
> +	},
> +	[ITEM_L2TPV2_MSG_CTRL_TUNNEL_ID] = {
> +		.name = "tunnel_id",
> +		.help = "tunnel identifier",
> +		.next = NEXT(NEXT_ENTRY(ITEM_L2TPV2_MSG_CTRL_TUNNEL_ID,
> +					ITEM_L2TPV2_COMMON, ITEM_NEXT),
> +			     NEXT_ENTRY(COMMON_UNSIGNED),
> +			     item_param),
> +		.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2,
> +					     hdr.type3.tunnel_id)),
> +	},
> +	[ITEM_L2TPV2_MSG_CTRL_SESSION_ID] = {
> +		.name = "session_id",
> +		.help = "session identifier",
> +		.next = NEXT(NEXT_ENTRY(ITEM_L2TPV2_MSG_CTRL_SESSION_ID,
> +					ITEM_L2TPV2_COMMON, ITEM_NEXT),
> +			     NEXT_ENTRY(COMMON_UNSIGNED),
> +			     item_param),
> +		.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2,
> +					     hdr.type3.session_id)),
> +	},
> +	[ITEM_L2TPV2_MSG_CTRL_NS] = {
> +		.name = "ns",
> +		.help = "sequence number for message",
> +		.next = NEXT(NEXT_ENTRY(ITEM_L2TPV2_MSG_CTRL_NS,
> +					ITEM_L2TPV2_COMMON, ITEM_NEXT),
> +			     NEXT_ENTRY(COMMON_UNSIGNED),
> +			     item_param),
> +		.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2,
> +					     hdr.type3.ns)),
> +	},
> +	[ITEM_L2TPV2_MSG_CTRL_NR] = {
> +		.name = "nr",
> +		.help = "sequence number for next receive message",
> +		.next = NEXT(NEXT_ENTRY(ITEM_L2TPV2_MSG_CTRL_NS,
> +					ITEM_L2TPV2_COMMON, ITEM_NEXT),
> +			     NEXT_ENTRY(COMMON_UNSIGNED),
> +			     item_param),
> +		.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2,
> +					     hdr.type3.nr)),
> +	},
> +	[ITEM_PPP] = {
> +		.name = "ppp",
> +		.help = "match ppp header",
> +		.priv = PRIV_ITEM(PPP, sizeof(struct rte_flow_item_ppp)),
> +		.next = NEXT(item_ppp),
> +		.call = parse_vc,
> +	},
> +	[ITEM_PPP_ADDR] = {
> +		.name = "addr",
> +		.help = "ppp address",
> +		.next = NEXT(item_ppp, NEXT_ENTRY(COMMON_UNSIGNED),
> +			     item_param),
> +		.args = ARGS(ARGS_ENTRY(struct rte_flow_item_ppp, hdr.addr)),
> +	},
> +	[ITEM_PPP_CTRL] = {
> +		.name = "ctrl",
> +		.help = "ppp control",
> +		.next = NEXT(item_ppp, NEXT_ENTRY(COMMON_UNSIGNED),
> +			     item_param),
> +		.args = ARGS(ARGS_ENTRY(struct rte_flow_item_ppp, hdr.ctrl)),
> +	},
> +	[ITEM_PPP_PROTO_ID] = {
> +		.name = "proto_id",
> +		.help = "ppp protocol id",
> +		.next = NEXT(item_ppp, NEXT_ENTRY(COMMON_UNSIGNED),
> +			     item_param),
> +		.args = ARGS(ARGS_ENTRY(struct rte_flow_item_ppp,
> +					hdr.proto_id)),
> +	},
>  	/* Validate/create actions. */
>  	[ACTIONS] = {
>  		.name = "actions",
> @@ -5569,6 +5763,57 @@ parse_vc_item_ecpri_type(struct context *ctx, const struct token *token,
>  	return len;
>  }
> 
> +/** Parse L2TPV2 common header type field. */ static int
> +parse_vc_item_l2tpv2_type(struct context *ctx, const struct token *token,
> +			 const char *str, unsigned int len,
> +			 void *buf, unsigned int size)
> +{
> +	struct rte_flow_item_l2tpv2 *l2tpv2;
> +	struct rte_flow_item_l2tpv2 *l2tpv2_mask;
> +	struct rte_flow_item *item;
> +	uint32_t data_size;
> +	uint8_t msg_type = 0;
> +	struct buffer *out = buf;
> +	const struct arg *arg;
> +
> +	(void)size;
> +	/* Token name must match. */
> +	if (parse_default(ctx, token, str, len, NULL, 0) < 0)
> +		return -1;
> +	switch (ctx->curr) {
> +	case ITEM_L2TPV2_COMMON_TYPE_DATA_L:
> +		msg_type |= 0x4000;
> +		break;
> +	case ITEM_L2TPV2_COMMON_TYPE_CTRL:
> +		msg_type |= 0xC800;
> +		break;
> +	default:
> +		return -1;
> +	}
> +	if (!ctx->object)
> +		return len;
> +	arg = pop_args(ctx);
> +	if (!arg)
> +		return -1;
> +	l2tpv2 = (struct rte_flow_item_l2tpv2 *)out->args.vc.data;
> +	l2tpv2->hdr.common.flags_version |= msg_type;
> +	data_size = ctx->objdata / 3; /* spec, last, mask */
> +	l2tpv2_mask = (struct rte_flow_item_l2tpv2 *)(out->args.vc.data +
> +						    (data_size * 2));
> +	l2tpv2_mask->hdr.common.flags_version = 0xFFFF;
> +	if (arg->hton) {
> +		l2tpv2->hdr.common.flags_version =
> +			rte_cpu_to_be_16(l2tpv2->hdr.common.flags_version);
> +		l2tpv2_mask->hdr.common.flags_version =
> +		    rte_cpu_to_be_16(l2tpv2_mask->hdr.common.flags_version);
> +	}
> +	item = &out->args.vc.pattern[out->args.vc.pattern_n - 1];
> +	item->spec = l2tpv2;
> +	item->mask = l2tpv2_mask;
> +	return len;
> +}
> +
>  /** Parse meter color action type. */
>  static int
>  parse_vc_action_meter_color_type(struct context *ctx, const struct token *token, @@ -8461,6
> +8706,12 @@ flow_item_default_mask(const struct rte_flow_item *item)
>  	case RTE_FLOW_ITEM_TYPE_REPRESENTED_PORT:
>  		mask = &rte_flow_item_ethdev_mask;
>  		break;
> +	case RTE_FLOW_ITEM_TYPE_L2TPV2:
> +		mask = &rte_flow_item_l2tpv2_mask;
> +		break;
> +	case RTE_FLOW_ITEM_TYPE_PPP:
> +		mask = &rte_flow_item_ppp_mask;
> +		break;
>  	default:
>  		break;
>  	}
> --
> 2.25.1

I see that you are missing updating the cmd_set_raw_parsed function, without it
raw encap/decap will not work for your new tunnel header.

Best,
Ori


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

* Re: [dpdk-dev] [PATCH v4 1/3] ethdev: support PPP and L2TPV2 procotol
  2021-10-18 10:56         ` Ori Kam
@ 2021-10-18 12:39           ` Zhang, Qi Z
  0 siblings, 0 replies; 71+ messages in thread
From: Zhang, Qi Z @ 2021-10-18 12:39 UTC (permalink / raw)
  To: Ori Kam, Wang, Jie1X, dev
  Cc: Yigit, Ferruh, NBU-Contact-Thomas Monjalon, andrew.rybchenko, Li,
	Xiaoyun, Yang,  SteveX, Wu, Jingjing, Xing, Beilei, Wu, Wenjun1



> -----Original Message-----
> From: Ori Kam <orika@nvidia.com>
> Sent: Monday, October 18, 2021 6:57 PM
> To: Wang, Jie1X <jie1x.wang@intel.com>; dev@dpdk.org
> Cc: Yigit, Ferruh <ferruh.yigit@intel.com>; NBU-Contact-Thomas Monjalon
> <thomas@monjalon.net>; andrew.rybchenko@oktetlabs.ru; Li, Xiaoyun
> <xiaoyun.li@intel.com>; Yang, SteveX <stevex.yang@intel.com>; Wu, Jingjing
> <jingjing.wu@intel.com>; Xing, Beilei <beilei.xing@intel.com>; Wu, Wenjun1
> <wenjun1.wu@intel.com>; Zhang, Qi Z <qi.z.zhang@intel.com>
> Subject: RE: [PATCH v4 1/3] ethdev: support PPP and L2TPV2 procotol
> 
> Hi Jie,
> 
> I realy don't know why you keep insisting about the RSS?
> you keep using it in the documentation, the reason I care is that you are not
> doing anything with RSS, and you can't have RSS on the PPP or
> L2TPV2 fields right?
> 
> > -----Original Message-----
> > From: Jie Wang <jie1x.wang@intel.com>
> > Sent: Monday, October 18, 2021 12:34 PM
> > To: dev@dpdk.org
> > Subject: [PATCH v4 1/3] ethdev: support PPP and L2TPV2 procotol
> >
> > Added flow pattern items and header formats of L2TPv2 and PPP.
> >
> > Signed-off-by: Wenjun Wu <wenjun1.wu@intel.com>
> > Signed-off-by: Jie Wang <jie1x.wang@intel.com>
> > ---
> >  doc/guides/prog_guide/rte_flow.rst     |  25 +++
> >  doc/guides/rel_notes/release_21_11.rst |   5 +
> >  lib/ethdev/rte_flow.c                  |   2 +
> >  lib/ethdev/rte_flow.h                  |  66 ++++++++
> >  lib/net/rte_l2tpv2.h                   | 214
> +++++++++++++++++++++++++
> >  lib/net/rte_ppp.h                      |  35 ++++
> >  6 files changed, 347 insertions(+)
> >  create mode 100644 lib/net/rte_l2tpv2.h  create mode 100644
> > lib/net/rte_ppp.h
> >
> > diff --git a/doc/guides/prog_guide/rte_flow.rst
> > b/doc/guides/prog_guide/rte_flow.rst
> > index fa05fe0845..6277c641ef 100644
> > --- a/doc/guides/prog_guide/rte_flow.rst
> > +++ b/doc/guides/prog_guide/rte_flow.rst
> > @@ -1548,6 +1548,31 @@ This item is meant to use the same structure as
> `Item:
> > PORT_REPRESENTOR`_.
> >
> >  See also `Action: REPRESENTED_PORT`_.
> >
> > +Item: ``L2TPV2``
> > +^^^^^^^^^^^^^^^^^^^
> > +
> > +Matches a L2TPv2 header.
> > +
> > +- ``flags_version``: flags(12b), version(4b).
> > +- ``length``: total length of the message.
> > +- ``tunnel_id``: identifier for the control connection.
> > +- ``session_id``: identifier for a session within a tunnel.
> > +- ``ns``: sequence number for this date or control message.
> > +- ``nr``: sequence number expected in the next control message to be
> received.
> > +- ``offset_size``: offset of payload data.
> > +- ``offset_padding``: offset padding, variable length.
> > +- Default ``mask`` matches flags_version only.
> > +
> > +Item: ``PPP``
> > +^^^^^^^^^^^^^^^^^^^
> > +
> > +Matches a PPP header.
> > +
> > +- ``addr``: ppp address.
> > +- ``ctrl``: ppp control.
> > +- ``proto_id``: ppp protocol identifier.
> > +- Default ``mask`` matches addr, ctrl, proto_id.
> > +
> >  Actions
> >  ~~~~~~~
> >
> > diff --git a/doc/guides/rel_notes/release_21_11.rst
> > b/doc/guides/rel_notes/release_21_11.rst
> > index ec2a788789..e1b23ce0e9 100644
> > --- a/doc/guides/rel_notes/release_21_11.rst
> > +++ b/doc/guides/rel_notes/release_21_11.rst
> > @@ -98,6 +98,11 @@ New Features
> >
> >    Added an ethdev API which can help users get device configuration.
> >
> > +* **Added L2TPV2 and PPP protocol support in rte_flow.**
> > +
> > +  Added flow pattern items and header formats of L2TPv2 and PPP to
> > + support  PPP over L2TPv2 over UDP protocol RSS Hash.
> 
> Why RSS hash appears here?

+1, from ethdev API's perspective, we just add a new protocol type here, nothing more.

> 
> > +
> >  * **Updated AF_XDP PMD.**
> >
> >    * Disabled secondary process support.
> > diff --git a/lib/ethdev/rte_flow.c b/lib/ethdev/rte_flow.c index
> > 29f2b0e954..0bfbeb73e8 100644
> > --- a/lib/ethdev/rte_flow.c
> > +++ b/lib/ethdev/rte_flow.c
> > @@ -102,6 +102,8 @@ static const struct rte_flow_desc_data
> rte_flow_desc_item[] = {
> >  	MK_FLOW_ITEM(CONNTRACK, sizeof(uint32_t)),
> >  	MK_FLOW_ITEM(PORT_REPRESENTOR, sizeof(struct
> rte_flow_item_ethdev)),
> >  	MK_FLOW_ITEM(REPRESENTED_PORT, sizeof(struct
> rte_flow_item_ethdev)),
> > +	MK_FLOW_ITEM(L2TPV2, sizeof(struct rte_flow_item_l2tpv2)),
> > +	MK_FLOW_ITEM(PPP, sizeof(struct rte_flow_item_ppp)),
> >  };
> >
> >  /** Generate flow_action[] entry. */
> > diff --git a/lib/ethdev/rte_flow.h b/lib/ethdev/rte_flow.h index
> > d5bfdaaaf2..2bc825b567 100644
> > --- a/lib/ethdev/rte_flow.h
> > +++ b/lib/ethdev/rte_flow.h
> > @@ -35,6 +35,8 @@
> >  #include <rte_mbuf_dyn.h>
> >  #include <rte_meter.h>
> >  #include <rte_gtp.h>
> > +#include <rte_l2tpv2.h>
> > +#include <rte_ppp.h>
> >
> >  #ifdef __cplusplus
> >  extern "C" {
> > @@ -635,6 +637,21 @@ enum rte_flow_item_type {
> >  	 * @see struct rte_flow_item_ethdev
> >  	 */
> >  	RTE_FLOW_ITEM_TYPE_REPRESENTED_PORT,
> > +
> > +	/**
> > +	 * Matches L2TPV2 Header.
> > +	 *
> > +	 * See struct rte_flow_item_l2tpv2.
> > +	 */
> > +	RTE_FLOW_ITEM_TYPE_L2TPV2,
> > +
> > +	/**
> > +	 * Matches PPP Header.
> > +	 *
> > +	 * See struct rte_flow_item_ppp.
> > +	 */
> > +	RTE_FLOW_ITEM_TYPE_PPP,
> > +
> >  };
> >
> >  /**
> > @@ -1891,6 +1908,55 @@ static const struct rte_flow_item_ethdev
> > rte_flow_item_ethdev_mask = { };  #endif
> >
> > +/**
> > + * @warning
> > + * @b EXPERIMENTAL: this structure may change without prior notice
> > + * RTE_FLOW_ITEM_TYPE_L2TPV2
> > + *
> > + * Matches L2TPv2 Header
> > + */
> > +struct rte_flow_item_l2tpv2 {
> > +	struct rte_l2tpv2_combined_msg_hdr hdr; };
> > +
> > +/** Default mask for RTE_FLOW_ITEM_TYPE_L2TPV2. */ #ifndef
> > +__cplusplus static const struct rte_flow_item_l2tpv2
> rte_flow_item_l2tpv2_mask = {
> > +	/*
> > +	 * flags and version bit mask
> > +	 * 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0
> > +	 * T L x x S x O P x x x x V V V V
> > +	 */
> > +	.hdr = {
> > +		.common = {
> > +			.flags_version = 0xcb0f,
> > +		},
> > +	},
> > +};
> > +#endif
> > +
> > +/**
> > + * @warning
> > + * @b EXPERIMENTAL: this structure may change without prior notice
> > + * RTE_FLOW_ITEM_TYPE_PPP
> > + *
> > + * Matches PPP Header
> > + */
> > +struct rte_flow_item_ppp {
> > +	struct rte_ppp_hdr hdr;
> > +};
> > +
> > +/** Default mask for RTE_FLOW_ITEM_TYPE_PPP. */ #ifndef __cplusplus
> > +static const struct rte_flow_item_ppp rte_flow_item_ppp_mask = {
> > +	.hdr = {
> > +		.addr = 0xff,
> > +		.ctrl = 0xff,
> > +		.proto_id = 0xffff,
> > +	}
> > +};
> > +#endif
> > +
> >  /**
> >   * Matching pattern item definition.
> >   *
> > diff --git a/lib/net/rte_l2tpv2.h b/lib/net/rte_l2tpv2.h new file mode
> > 100644 index 0000000000..aea3c689be
> > --- /dev/null
> > +++ b/lib/net/rte_l2tpv2.h
> > @@ -0,0 +1,214 @@
> > +/* SPDX-License-Identifier: BSD-3-Clause
> > + * Copyright 2021 Mellanox Technologies, Ltd  */
> > +
> > +#ifndef _RTE_L2TPV2_H_
> > +#define _RTE_L2TPV2_H_
> > +
> > +/**
> > + * @file
> > + *
> > + * L2TP header:
> > + *  0                   1                   2
> 3
> > + *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
> > + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
> > + * |T|L|x|x|S|x|O|P|x|x|x|x|  Ver  |          Length (opt)
> |
> > + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
> > + * |           Tunnel ID           |           Session ID          |
> > + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
> > + * |             Ns (opt)          |             Nr (opt)          |
> > + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
> > + * |      Offset Size (opt)        |    Offset pad... (opt)
> > + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
> > + *
> > + * The Type (T) bit indicates the type of message. It is set to 0 for
> > +a data
> > + * message and 1 for a control message.
> > + *
> > + * If the Length (L) bit is 1, the Length field is present. This bit
> > +MUST be
> > + * set to 1 for control messages.
> > + *
> > + * The x bits are reserved for future extensions. All reserved bits
> > +MUST
> > + * be set to 0 on outgoing messages and ignored on incoming messages.
> > + *
> > + * If the Sequence (S) bit is set to 1 the Ns and Nr fields are present.
> > + * The S bit MUST be set to 1 for control messages.
> > + *
> > + * If the Offset (O) bit is 1, the Offset Size field is present. The
> > +O
> > + * bit MUST be set to 0 for control messages.
> > + *
> > + * If the Priority (P) bit is 1, this data message should receive
> > + * preferential treatment in its local queuing and transmission.
> > + * The P bit MUST be set to 0 for control messages.
> > + *
> > + * Ver MUST be 2, indicating the version of the L2TP data message header.
> > + *
> > + * The Length field indicates the total length of the message in octets.
> > + *
> > + * Tunnel ID indicates the identifier for the control connection.
> > + *
> > + * Session ID indicates the identifier for a session within a tunnel.
> > + *
> > + * Ns indicates the sequence number for this data or control message.
> > + *
> > + * Nr indicates the sequence number expected in the next control
> > +message
> > + * to be received.
> > + *
> > + * The Offset Size field, if present, specifies the number of octets
> > + * past the L2TP header at which the payload data is expected to start.
> > + * Actual data within the offset padding is undefined. If the offset
> > + * field is present, the L2TP header ends after the last octet of the
> > + * offset padding.
> > + */
> > +
> > +#include <stdint.h>
> > +#include <rte_byteorder.h>
> > +
> > +#ifdef __cplusplus
> > +extern "C" {
> > +#endif
> > +
> > +/**
> > + * L2TPv2 Common Header
> > + */
> > +RTE_STD_C11
> > +struct rte_l2tpv2_common_hdr {
> > +	union {
> > +		rte_be16_t flags_version;
> > +		struct {
> > +#if RTE_BYTE_ORDER == RTE_LITTLE_ENDIAN
> > +			rte_be16_t t:1;		/**< message Type */
> > +			rte_be16_t l:1;		/**< length option bit*/
> > +			rte_be16_t res1:2;	/**< reserved */
> > +			rte_be16_t s:1;		/**< ns/nr option bit*/
> > +			rte_be16_t res2:1;	/**< reserved */
> > +			rte_be16_t o:1;		/**< offset option bit*/
> > +			rte_be16_t p:1;		/**< priority option bit*/
> > +			rte_be16_t res3:4;	/**< reserved */
> > +			rte_be16_t ver:4;	/**< protocol version */
> > +#elif RTE_BYTE_ORDER == RTE_BIG_ENDIAN
> > +			rte_be16_t ver:4;	/**< protocol version */
> > +			rte_be16_t res3:4;	/**< reserved */
> > +			rte_be16_t p:1;		/**< priority option bit*/
> > +			rte_be16_t o:1;		/**< offset option bit*/
> > +			rte_be16_t res2:1;	/**< reserved */
> > +			rte_be16_t s:1;		/**< ns/nr option bit*/
> > +			rte_be16_t res1:2;	/**< reserved */
> > +			rte_be16_t l:1;		/**< length option bit*/
> > +			rte_be16_t t:1;		/**< message Type */
> > +#endif
> > +		};
> > +	};
> > +};
> > +
> > +/*
> > + * L2TPv2 message Header contains all options(length, ns, nr,
> > + * offset size, offset padding).
> > + */
> > +struct rte_l2tpv2_msg_with_all_options {
> > +	rte_be16_t length;		/**< length(16) */
> > +	rte_be16_t tunnel_id;		/**< tunnel id(16) */
> > +	rte_be16_t session_id;		/**< session id(16) */
> > +	rte_be16_t ns;			/**< Ns(16) */
> > +	rte_be16_t nr;			/**< Nr(16) */
> > +	rte_be16_t offset_size;		/**< offset size(16) */
> > +	uint8_t   *offset_padding;	/**< offset padding(variable length) */
> > +};
> > +
> > +/*
> > + * L2TPv2 message Header contains all options except length(ns, nr,
> > + * offset size, offset padding).
> > + */
> > +struct rte_l2tpv2_msg_without_length {
> > +	rte_be16_t tunnel_id;		/**< tunnel id(16) */
> > +	rte_be16_t session_id;		/**< session id(16) */
> > +	rte_be16_t ns;			/**< Ns(16) */
> > +	rte_be16_t nr;			/**< Nr(16) */
> > +	rte_be16_t offset_size;		/**< offset size(16) */
> > +	uint8_t   *offset_padding;	/**< offset padding(variable length) */
> > +};
> > +
> > +/*
> > + * L2TPv2 message Header contains all options except ns_nr(length,
> > + * offset size, offset padding).
> > + * Ns and Nr MUST be toghter.
> > + */
> > +struct rte_l2tpv2_msg_without_ns_nr {
> > +	rte_be16_t length;		/**< length(16) */
> > +	rte_be16_t tunnel_id;		/**< tunnel id(16) */
> > +	rte_be16_t session_id;		/**< session id(16) */
> > +	rte_be16_t offset_size;		/**< offset size(16) */
> > +	uint8_t   *offset_padding;	/**< offset padding(variable length) */
> > +};
> > +
> > +/*
> > + * L2TPv2 message Header contains all options except ns_nr(length, ns, nr).
> > + * offset size and offset padding MUST be toghter.
> > + */
> > +struct rte_l2tpv2_msg_without_offset {
> > +	rte_be16_t length;		/**< length(16) */
> > +	rte_be16_t tunnel_id;		/**< tunnel id(16) */
> > +	rte_be16_t session_id;		/**< session id(16) */
> > +	rte_be16_t ns;			/**< Ns(16) */
> > +	rte_be16_t nr;			/**< Nr(16) */
> > +};
> > +
> > +/*
> > + * L2TPv2 message Header contains options offset size and offset padding.
> > + */
> > +struct rte_l2tpv2_msg_with_offset {
> > +	rte_be16_t tunnel_id;		/**< tunnel id(16) */
> > +	rte_be16_t session_id;		/**< session id(16) */
> > +	rte_be16_t offset_size;		/**< offset size(16) */
> > +	uint8_t   *offset_padding;	/**< offset padding(variable length) */
> > +};
> > +
> > +/*
> > + * L2TPv2 message Header contains options ns and nr.
> > + */
> > +struct rte_l2tpv2_msg_with_ns_nr {
> > +	rte_be16_t tunnel_id;		/**< tunnel id(16) */
> > +	rte_be16_t session_id;		/**< session id(16) */
> > +	rte_be16_t ns;			/**< Ns(16) */
> > +	rte_be16_t nr;			/**< Nr(16) */
> > +};
> > +
> > +/*
> > + * L2TPv2 message Header contains option length.
> > + */
> > +struct rte_l2tpv2_msg_with_length {
> > +	rte_be16_t length;		/**< length(16) */
> > +	rte_be16_t tunnel_id;		/**< tunnel id(16) */
> > +	rte_be16_t session_id;		/**< session id(16) */
> > +};
> > +
> > +/*
> > + * L2TPv2 message Header without all options.
> > + */
> > +struct rte_l2tpv2_msg_without_all_options {
> > +	rte_be16_t tunnel_id;		/**< tunnel id(16) */
> > +	rte_be16_t session_id;		/**< session id(16) */
> > +};
> > +
> > +/**
> > + * L2TPv2 Combined Message Header Format: Common Header + Options
> */
> > +RTE_STD_C11
> > +struct rte_l2tpv2_combined_msg_hdr {
> > +	struct rte_l2tpv2_common_hdr common;
> > +	union {
> > +		struct rte_l2tpv2_msg_with_all_options type0;
> > +		struct rte_l2tpv2_msg_without_length type1;
> > +		struct rte_l2tpv2_msg_without_ns_nr type2;
> > +		struct rte_l2tpv2_msg_without_offset type3;
> > +		struct rte_l2tpv2_msg_with_offset type4;
> > +		struct rte_l2tpv2_msg_with_ns_nr type5;
> > +		struct rte_l2tpv2_msg_with_length type6;
> > +		struct rte_l2tpv2_msg_without_all_options type7;
> > +	};
> > +};
> > +
> > +#ifdef __cplusplus
> > +}
> > +#endif
> > +
> > +#endif /* _RTE_L2TPV2_H_ */
> > diff --git a/lib/net/rte_ppp.h b/lib/net/rte_ppp.h new file mode
> > 100644 index
> > 0000000000..9ea633baa7
> > --- /dev/null
> > +++ b/lib/net/rte_ppp.h
> > @@ -0,0 +1,35 @@
> > +/* SPDX-License-Identifier: BSD-3-Clause
> > + * Copyright 2021 Mellanox Technologies, Ltd  */
> > +
> > +#ifndef _RTE_PPP_H_
> > +#define _RTE_PPP_H_
> > +
> > +/**
> > + * @file
> > + *
> > + * PPP headers definition.
> > + *
> > + */
> > +
> > +#include <stdint.h>
> > +#include <rte_byteorder.h>
> > +
> > +#ifdef __cplusplus
> > +extern "C" {
> > +#endif
> > +
> > +/**
> > + * PPP Header
> > + */
> > +struct rte_ppp_hdr {
> > +	uint8_t addr; /**< ppp address(8) */
> > +	uint8_t ctrl; /**< ppp control(8) */
> > +	rte_be16_t proto_id; /**< ppp protocol id(16) */ } __rte_packed;
> > +
> > +#ifdef __cplusplus
> > +}
> > +#endif
> > +
> > +#endif /* _RTE_PPP_H_ */
> > --
> > 2.25.1
> 
> Best,
> Ori

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

* Re: [dpdk-dev] [PATCH v4 3/3] app/testpmd: support L2TPV2 and PPP protocol pattern
  2021-10-18 11:03         ` Ori Kam
@ 2021-10-18 12:41           ` Zhang, Qi Z
  0 siblings, 0 replies; 71+ messages in thread
From: Zhang, Qi Z @ 2021-10-18 12:41 UTC (permalink / raw)
  To: Ori Kam, Wang, Jie1X, dev
  Cc: Yigit, Ferruh, NBU-Contact-Thomas Monjalon, andrew.rybchenko, Li,
	Xiaoyun, Yang,  SteveX, Wu, Jingjing, Xing, Beilei, Wu, Wenjun1



> -----Original Message-----
> From: Ori Kam <orika@nvidia.com>
> Sent: Monday, October 18, 2021 7:03 PM
> To: Wang, Jie1X <jie1x.wang@intel.com>; dev@dpdk.org
> Cc: Yigit, Ferruh <ferruh.yigit@intel.com>; NBU-Contact-Thomas Monjalon
> <thomas@monjalon.net>; andrew.rybchenko@oktetlabs.ru; Li, Xiaoyun
> <xiaoyun.li@intel.com>; Yang, SteveX <stevex.yang@intel.com>; Wu, Jingjing
> <jingjing.wu@intel.com>; Xing, Beilei <beilei.xing@intel.com>; Wu, Wenjun1
> <wenjun1.wu@intel.com>; Zhang, Qi Z <qi.z.zhang@intel.com>
> Subject: RE: [PATCH v4 3/3] app/testpmd: support L2TPV2 and PPP protocol
> pattern
> 
> Hi Jie,
> 
> 
> > -----Original Message-----
> > From: Jie Wang <jie1x.wang@intel.com>
> > Sent: Monday, October 18, 2021 12:34 PM
> > To: dev@dpdk.org
> > Subject: [PATCH v4 3/3] app/testpmd: support L2TPV2 and PPP protocol
> > pattern
> >
> > Add support for test-pmd to parse protocol pattern L2TPv2 and PPP.
> >
> > Signed-off-by: Wenjun Wu <wenjun1.wu@intel.com>
> > Signed-off-by: Jie Wang <jie1x.wang@intel.com>
> > ---
> 
> 
> 
> >  app/test-pmd/cmdline_flow.c | 251
> > ++++++++++++++++++++++++++++++++++++
> >  1 file changed, 251 insertions(+)
> >
> > diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
> > index
> > a90822b660..c1046e3e28 100644
> > --- a/app/test-pmd/cmdline_flow.c
> > +++ b/app/test-pmd/cmdline_flow.c
> > @@ -310,6 +310,23 @@ enum index {
> >  	ITEM_PORT_REPRESENTOR_PORT_ID,
> >  	ITEM_REPRESENTED_PORT,
> >  	ITEM_REPRESENTED_PORT_ETHDEV_PORT_ID,
> > +	ITEM_L2TPV2,
> > +	ITEM_L2TPV2_COMMON,
> > +	ITEM_L2TPV2_COMMON_TYPE,
> > +	ITEM_L2TPV2_COMMON_TYPE_DATA_L,
> > +	ITEM_L2TPV2_COMMON_TYPE_CTRL,
> > +	ITEM_L2TPV2_MSG_DATA_L_LENGTH,
> > +	ITEM_L2TPV2_MSG_DATA_L_TUNNEL_ID,
> > +	ITEM_L2TPV2_MSG_DATA_L_SESSION_ID,
> > +	ITEM_L2TPV2_MSG_CTRL_LENGTH,
> > +	ITEM_L2TPV2_MSG_CTRL_TUNNEL_ID,
> > +	ITEM_L2TPV2_MSG_CTRL_SESSION_ID,
> > +	ITEM_L2TPV2_MSG_CTRL_NS,
> > +	ITEM_L2TPV2_MSG_CTRL_NR,
> > +	ITEM_PPP,
> > +	ITEM_PPP_ADDR,
> > +	ITEM_PPP_CTRL,
> > +	ITEM_PPP_PROTO_ID,
> >
> >  	/* Validate/create actions. */
> >  	ACTIONS,
> > @@ -1018,6 +1035,8 @@ static const enum index next_item[] = {
> >  	ITEM_CONNTRACK,
> >  	ITEM_PORT_REPRESENTOR,
> >  	ITEM_REPRESENTED_PORT,
> > +	ITEM_L2TPV2,
> > +	ITEM_PPP,
> >  	END_SET,
> >  	ZERO,
> >  };
> > @@ -1398,6 +1417,31 @@ static const enum index item_represented_port[]
> = {
> >  	ZERO,
> >  };
> >
> > +static const enum index item_l2tpv2[] = {
> > +	ITEM_L2TPV2_COMMON,
> > +	ITEM_NEXT,
> > +	ZERO,
> > +};
> > +
> > +static const enum index item_l2tpv2_common[] = {
> > +	ITEM_L2TPV2_COMMON_TYPE,
> > +	ZERO,
> > +};
> > +
> > +static const enum index item_l2tpv2_common_type[] = {
> > +	ITEM_L2TPV2_COMMON_TYPE_DATA_L,
> > +	ITEM_L2TPV2_COMMON_TYPE_CTRL,
> > +	ZERO,
> > +};
> > +
> > +static const enum index item_ppp[] = {
> > +	ITEM_PPP_ADDR,
> > +	ITEM_PPP_CTRL,
> > +	ITEM_PPP_PROTO_ID,
> > +	ITEM_NEXT,
> > +	ZERO,
> > +};
> > +
> >  static const enum index next_action[] = {
> >  	ACTION_END,
> >  	ACTION_VOID,
> > @@ -1781,6 +1825,9 @@ static int parse_vc_conf(struct context *, const
> > struct token *,  static int parse_vc_item_ecpri_type(struct context *, const
> struct token *,
> >  				    const char *, unsigned int,
> >  				    void *, unsigned int);
> > +static int parse_vc_item_l2tpv2_type(struct context *, const struct token *,
> > +				    const char *, unsigned int,
> > +				    void *, unsigned int);
> >  static int parse_vc_action_meter_color_type(struct context *,
> >  					const struct token *,
> >  					const char *, unsigned int, void *, @@ -3682,6
> +3729,153 @@
> > static const struct token token_list[] = {
> >  			     item_param),
> >  		.args = ARGS(ARGS_ENTRY(struct rte_flow_item_ethdev, port_id)),
> >  	},
> > +	[ITEM_L2TPV2] = {
> > +		.name = "l2tpv2",
> > +		.help = "match l2tpv2 header",
> > +		.priv = PRIV_ITEM(L2TPV2, sizeof(struct rte_flow_item_l2tpv2)),
> > +		.next = NEXT(item_l2tpv2),
> > +		.call = parse_vc,
> > +	},
> > +	[ITEM_L2TPV2_COMMON] = {
> > +		.name = "common",
> > +		.help = "l2tpv2 common header",
> > +		.next = NEXT(item_l2tpv2_common),
> > +	},
> > +	[ITEM_L2TPV2_COMMON_TYPE] = {
> > +		.name = "type",
> > +		.help = "type of common header",
> > +		.next = NEXT(item_l2tpv2_common_type),
> > +		.args = ARGS(ARG_ENTRY_HTON(struct rte_flow_item_l2tpv2)),
> > +	},
> > +	[ITEM_L2TPV2_COMMON_TYPE_DATA_L] = {
> > +		.name = "data_l",
> > +		.help = "Type #6: data message with length option",
> > +		.next = NEXT(NEXT_ENTRY(ITEM_L2TPV2_MSG_DATA_L_LENGTH,
> > +					ITEM_L2TPV2_MSG_DATA_L_TUNNEL_ID,
> > +					ITEM_L2TPV2_MSG_DATA_L_SESSION_ID,
> > +					ITEM_NEXT)),
> > +		.call = parse_vc_item_l2tpv2_type,
> > +	},
> > +	[ITEM_L2TPV2_MSG_DATA_L_LENGTH] = {
> > +		.name = "length",
> > +		.help = "message length",
> > +		.next = NEXT(NEXT_ENTRY(ITEM_L2TPV2_MSG_DATA_L_LENGTH,
> > +					ITEM_L2TPV2_COMMON, ITEM_NEXT),
> > +			     NEXT_ENTRY(COMMON_UNSIGNED),
> > +			     item_param),
> > +		.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2,
> > +					     hdr.type6.length)),
> > +	},
> > +	[ITEM_L2TPV2_MSG_DATA_L_TUNNEL_ID] = {
> > +		.name = "tunnel_id",
> > +		.help = "tunnel identifier",
> > +		.next = NEXT(NEXT_ENTRY(ITEM_L2TPV2_MSG_DATA_L_TUNNEL_ID,
> > +					ITEM_L2TPV2_COMMON, ITEM_NEXT),
> > +			     NEXT_ENTRY(COMMON_UNSIGNED),
> > +			     item_param),
> > +		.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2,
> > +					     hdr.type6.tunnel_id)),
> > +	},
> > +	[ITEM_L2TPV2_MSG_DATA_L_SESSION_ID] = {
> > +		.name = "session_id",
> > +		.help = "session identifier",
> > +		.next = NEXT(NEXT_ENTRY(ITEM_L2TPV2_MSG_DATA_L_SESSION_ID,
> > +					ITEM_L2TPV2_COMMON, ITEM_NEXT),
> > +			     NEXT_ENTRY(COMMON_UNSIGNED),
> > +			     item_param),
> > +		.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2,
> > +					     hdr.type6.session_id)),
> > +	},
> > +	[ITEM_L2TPV2_COMMON_TYPE_CTRL] = {
> > +		.name = "control",
> > +		.help = "Type #3: conrtol message contains length, ns, nr options",
> > +		.next = NEXT(NEXT_ENTRY(ITEM_L2TPV2_MSG_CTRL_LENGTH,
> > +					ITEM_L2TPV2_MSG_CTRL_TUNNEL_ID,
> > +					ITEM_L2TPV2_MSG_CTRL_SESSION_ID,
> > +					ITEM_L2TPV2_MSG_CTRL_NS,
> > +					ITEM_L2TPV2_MSG_CTRL_NR,
> > +					ITEM_NEXT)),
> > +		.call = parse_vc_item_l2tpv2_type,
> > +	},
> > +	[ITEM_L2TPV2_MSG_CTRL_LENGTH] = {
> > +		.name = "length",
> > +		.help = "message length",
> > +		.next = NEXT(NEXT_ENTRY(ITEM_L2TPV2_MSG_CTRL_LENGTH,
> > +					ITEM_L2TPV2_COMMON, ITEM_NEXT),
> > +			     NEXT_ENTRY(COMMON_UNSIGNED),
> > +			     item_param),
> > +		.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2,
> > +					     hdr.type3.length)),
> > +	},
> > +	[ITEM_L2TPV2_MSG_CTRL_TUNNEL_ID] = {
> > +		.name = "tunnel_id",
> > +		.help = "tunnel identifier",
> > +		.next = NEXT(NEXT_ENTRY(ITEM_L2TPV2_MSG_CTRL_TUNNEL_ID,
> > +					ITEM_L2TPV2_COMMON, ITEM_NEXT),
> > +			     NEXT_ENTRY(COMMON_UNSIGNED),
> > +			     item_param),
> > +		.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2,
> > +					     hdr.type3.tunnel_id)),
> > +	},
> > +	[ITEM_L2TPV2_MSG_CTRL_SESSION_ID] = {
> > +		.name = "session_id",
> > +		.help = "session identifier",
> > +		.next = NEXT(NEXT_ENTRY(ITEM_L2TPV2_MSG_CTRL_SESSION_ID,
> > +					ITEM_L2TPV2_COMMON, ITEM_NEXT),
> > +			     NEXT_ENTRY(COMMON_UNSIGNED),
> > +			     item_param),
> > +		.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2,
> > +					     hdr.type3.session_id)),
> > +	},
> > +	[ITEM_L2TPV2_MSG_CTRL_NS] = {
> > +		.name = "ns",
> > +		.help = "sequence number for message",
> > +		.next = NEXT(NEXT_ENTRY(ITEM_L2TPV2_MSG_CTRL_NS,
> > +					ITEM_L2TPV2_COMMON, ITEM_NEXT),
> > +			     NEXT_ENTRY(COMMON_UNSIGNED),
> > +			     item_param),
> > +		.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2,
> > +					     hdr.type3.ns)),
> > +	},
> > +	[ITEM_L2TPV2_MSG_CTRL_NR] = {
> > +		.name = "nr",
> > +		.help = "sequence number for next receive message",
> > +		.next = NEXT(NEXT_ENTRY(ITEM_L2TPV2_MSG_CTRL_NS,
> > +					ITEM_L2TPV2_COMMON, ITEM_NEXT),
> > +			     NEXT_ENTRY(COMMON_UNSIGNED),
> > +			     item_param),
> > +		.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2,
> > +					     hdr.type3.nr)),
> > +	},
> > +	[ITEM_PPP] = {
> > +		.name = "ppp",
> > +		.help = "match ppp header",
> > +		.priv = PRIV_ITEM(PPP, sizeof(struct rte_flow_item_ppp)),
> > +		.next = NEXT(item_ppp),
> > +		.call = parse_vc,
> > +	},
> > +	[ITEM_PPP_ADDR] = {
> > +		.name = "addr",
> > +		.help = "ppp address",
> > +		.next = NEXT(item_ppp, NEXT_ENTRY(COMMON_UNSIGNED),
> > +			     item_param),
> > +		.args = ARGS(ARGS_ENTRY(struct rte_flow_item_ppp, hdr.addr)),
> > +	},
> > +	[ITEM_PPP_CTRL] = {
> > +		.name = "ctrl",
> > +		.help = "ppp control",
> > +		.next = NEXT(item_ppp, NEXT_ENTRY(COMMON_UNSIGNED),
> > +			     item_param),
> > +		.args = ARGS(ARGS_ENTRY(struct rte_flow_item_ppp, hdr.ctrl)),
> > +	},
> > +	[ITEM_PPP_PROTO_ID] = {
> > +		.name = "proto_id",
> > +		.help = "ppp protocol id",
> > +		.next = NEXT(item_ppp, NEXT_ENTRY(COMMON_UNSIGNED),
> > +			     item_param),
> > +		.args = ARGS(ARGS_ENTRY(struct rte_flow_item_ppp,
> > +					hdr.proto_id)),
> > +	},
> >  	/* Validate/create actions. */
> >  	[ACTIONS] = {
> >  		.name = "actions",
> > @@ -5569,6 +5763,57 @@ parse_vc_item_ecpri_type(struct context *ctx,
> const struct token *token,
> >  	return len;
> >  }
> >
> > +/** Parse L2TPV2 common header type field. */ static int
> > +parse_vc_item_l2tpv2_type(struct context *ctx, const struct token *token,
> > +			 const char *str, unsigned int len,
> > +			 void *buf, unsigned int size)
> > +{
> > +	struct rte_flow_item_l2tpv2 *l2tpv2;
> > +	struct rte_flow_item_l2tpv2 *l2tpv2_mask;
> > +	struct rte_flow_item *item;
> > +	uint32_t data_size;
> > +	uint8_t msg_type = 0;
> > +	struct buffer *out = buf;
> > +	const struct arg *arg;
> > +
> > +	(void)size;
> > +	/* Token name must match. */
> > +	if (parse_default(ctx, token, str, len, NULL, 0) < 0)
> > +		return -1;
> > +	switch (ctx->curr) {
> > +	case ITEM_L2TPV2_COMMON_TYPE_DATA_L:
> > +		msg_type |= 0x4000;
> > +		break;
> > +	case ITEM_L2TPV2_COMMON_TYPE_CTRL:
> > +		msg_type |= 0xC800;
> > +		break;
> > +	default:
> > +		return -1;
> > +	}
> > +	if (!ctx->object)
> > +		return len;
> > +	arg = pop_args(ctx);
> > +	if (!arg)
> > +		return -1;
> > +	l2tpv2 = (struct rte_flow_item_l2tpv2 *)out->args.vc.data;
> > +	l2tpv2->hdr.common.flags_version |= msg_type;
> > +	data_size = ctx->objdata / 3; /* spec, last, mask */
> > +	l2tpv2_mask = (struct rte_flow_item_l2tpv2 *)(out->args.vc.data +
> > +						    (data_size * 2));
> > +	l2tpv2_mask->hdr.common.flags_version = 0xFFFF;
> > +	if (arg->hton) {
> > +		l2tpv2->hdr.common.flags_version =
> > +			rte_cpu_to_be_16(l2tpv2->hdr.common.flags_version);
> > +		l2tpv2_mask->hdr.common.flags_version =
> > +		    rte_cpu_to_be_16(l2tpv2_mask->hdr.common.flags_version);
> > +	}
> > +	item = &out->args.vc.pattern[out->args.vc.pattern_n - 1];
> > +	item->spec = l2tpv2;
> > +	item->mask = l2tpv2_mask;
> > +	return len;
> > +}
> > +
> >  /** Parse meter color action type. */  static int
> > parse_vc_action_meter_color_type(struct context *ctx, const struct
> > token *token, @@ -8461,6
> > +8706,12 @@ flow_item_default_mask(const struct rte_flow_item *item)
> >  	case RTE_FLOW_ITEM_TYPE_REPRESENTED_PORT:
> >  		mask = &rte_flow_item_ethdev_mask;
> >  		break;
> > +	case RTE_FLOW_ITEM_TYPE_L2TPV2:
> > +		mask = &rte_flow_item_l2tpv2_mask;
> > +		break;
> > +	case RTE_FLOW_ITEM_TYPE_PPP:
> > +		mask = &rte_flow_item_ppp_mask;
> > +		break;
> >  	default:
> >  		break;
> >  	}
> > --
> > 2.25.1
> 
> I see that you are missing updating the cmd_set_raw_parsed function, without
> it raw encap/decap will not work for your new tunnel header.

Hi Ori:

	We are not going to enable encap / decap feature for L2TPv2 (at least in this release), our goal is to create RSS / FDIR rule for packet with L2PTv2 header. 

Thanks
Qi

> 
> Best,
> Ori


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

* [dpdk-dev] [PATCH v5 0/3] support PPPoL2TPv2oUDP RSS Hash
  2021-10-18  9:33     ` [dpdk-dev] [PATCH v4 0/3] support PPPoL2TPv2oUDP RSS Hash Jie Wang
                         ` (2 preceding siblings ...)
  2021-10-18  9:33       ` [dpdk-dev] [PATCH v4 3/3] app/testpmd: support L2TPV2 and PPP protocol pattern Jie Wang
@ 2021-10-19  3:08       ` Jie Wang
  2021-10-19  3:08         ` [dpdk-dev] [PATCH v5 1/3] ethdev: support PPP and L2TPV2 procotol Jie Wang
                           ` (3 more replies)
  3 siblings, 4 replies; 71+ messages in thread
From: Jie Wang @ 2021-10-19  3:08 UTC (permalink / raw)
  To: dev
  Cc: orika, ferruh.yigit, thomas, andrew.rybchenko, xiaoyun.li,
	stevex.yang, jingjing.wu, beilei.xing, wenjun1.wu, qi.z.zhang,
	Jie Wang

Support IAVF PPPoL2TPv2oUDP RSS Hash. Required to distribute packets
based on inner IP src+dest address and TCP/UDP src+dest port.

---
v5: update release notes.
v4:
 * update commit log.
 * redefine PPP protocol header.
 * delete l2tpv2_encap.
v3:
 * add testpmd match ppp and l2tpv2 protocol header fields value.
 * add the code of l2tpv2_encap.
 * update the title of ethdev patch and adjust the position of
   the added code.

v2:
 * update the rte_flow.rst and release notes.
 * update l2tpv2 header format.

Jie Wang (3):
  ethdev: support PPP and L2TPV2 procotol
  net/iavf: support PPPoL2TPv2oUDP RSS Hash
  app/testpmd: support L2TPV2 and PPP protocol pattern

 app/test-pmd/cmdline_flow.c            | 251 +++++++++++++++++++++++++
 doc/guides/prog_guide/rte_flow.rst     |  25 +++
 doc/guides/rel_notes/release_21_11.rst |   4 +
 drivers/net/iavf/iavf_generic_flow.c   | 131 +++++++++++++
 drivers/net/iavf/iavf_generic_flow.h   |  15 ++
 drivers/net/iavf/iavf_hash.c           | 108 ++++++++++-
 lib/ethdev/rte_flow.c                  |   2 +
 lib/ethdev/rte_flow.h                  |  66 +++++++
 lib/net/rte_l2tpv2.h                   | 214 +++++++++++++++++++++
 lib/net/rte_ppp.h                      |  35 ++++
 10 files changed, 849 insertions(+), 2 deletions(-)
 create mode 100644 lib/net/rte_l2tpv2.h
 create mode 100644 lib/net/rte_ppp.h

-- 
2.25.1


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

* [dpdk-dev] [PATCH v5 1/3] ethdev: support PPP and L2TPV2 procotol
  2021-10-19  3:08       ` [dpdk-dev] [PATCH v5 0/3] support PPPoL2TPv2oUDP RSS Hash Jie Wang
@ 2021-10-19  3:08         ` Jie Wang
  2021-10-19  6:17           ` Ori Kam
  2021-10-19 10:30           ` Ferruh Yigit
  2021-10-19  3:08         ` [dpdk-dev] [PATCH v5 2/3] net/iavf: support PPPoL2TPv2oUDP RSS Hash Jie Wang
                           ` (2 subsequent siblings)
  3 siblings, 2 replies; 71+ messages in thread
From: Jie Wang @ 2021-10-19  3:08 UTC (permalink / raw)
  To: dev
  Cc: orika, ferruh.yigit, thomas, andrew.rybchenko, xiaoyun.li,
	stevex.yang, jingjing.wu, beilei.xing, wenjun1.wu, qi.z.zhang,
	Jie Wang

Added flow pattern items and header formats of L2TPv2 and PPP.

Signed-off-by: Wenjun Wu <wenjun1.wu@intel.com>
Signed-off-by: Jie Wang <jie1x.wang@intel.com>
---
 doc/guides/prog_guide/rte_flow.rst     |  25 +++
 doc/guides/rel_notes/release_21_11.rst |   4 +
 lib/ethdev/rte_flow.c                  |   2 +
 lib/ethdev/rte_flow.h                  |  66 ++++++++
 lib/net/rte_l2tpv2.h                   | 214 +++++++++++++++++++++++++
 lib/net/rte_ppp.h                      |  35 ++++
 6 files changed, 346 insertions(+)
 create mode 100644 lib/net/rte_l2tpv2.h
 create mode 100644 lib/net/rte_ppp.h

diff --git a/doc/guides/prog_guide/rte_flow.rst b/doc/guides/prog_guide/rte_flow.rst
index fa05fe0845..6277c641ef 100644
--- a/doc/guides/prog_guide/rte_flow.rst
+++ b/doc/guides/prog_guide/rte_flow.rst
@@ -1548,6 +1548,31 @@ This item is meant to use the same structure as `Item: PORT_REPRESENTOR`_.
 
 See also `Action: REPRESENTED_PORT`_.
 
+Item: ``L2TPV2``
+^^^^^^^^^^^^^^^^^^^
+
+Matches a L2TPv2 header.
+
+- ``flags_version``: flags(12b), version(4b).
+- ``length``: total length of the message.
+- ``tunnel_id``: identifier for the control connection.
+- ``session_id``: identifier for a session within a tunnel.
+- ``ns``: sequence number for this date or control message.
+- ``nr``: sequence number expected in the next control message to be received.
+- ``offset_size``: offset of payload data.
+- ``offset_padding``: offset padding, variable length.
+- Default ``mask`` matches flags_version only.
+
+Item: ``PPP``
+^^^^^^^^^^^^^^^^^^^
+
+Matches a PPP header.
+
+- ``addr``: ppp address.
+- ``ctrl``: ppp control.
+- ``proto_id``: ppp protocol identifier.
+- Default ``mask`` matches addr, ctrl, proto_id.
+
 Actions
 ~~~~~~~
 
diff --git a/doc/guides/rel_notes/release_21_11.rst b/doc/guides/rel_notes/release_21_11.rst
index bd6a388c9d..3286f8bd2a 100644
--- a/doc/guides/rel_notes/release_21_11.rst
+++ b/doc/guides/rel_notes/release_21_11.rst
@@ -98,6 +98,10 @@ New Features
 
   Added an ethdev API which can help users get device configuration.
 
+* **Added L2TPV2 and PPP protocol support in rte_flow.**
+
+  Added flow pattern items and header formats of L2TPv2 and PPP protocol.
+
 * **Updated AF_XDP PMD.**
 
   * Disabled secondary process support.
diff --git a/lib/ethdev/rte_flow.c b/lib/ethdev/rte_flow.c
index 29f2b0e954..0bfbeb73e8 100644
--- a/lib/ethdev/rte_flow.c
+++ b/lib/ethdev/rte_flow.c
@@ -102,6 +102,8 @@ static const struct rte_flow_desc_data rte_flow_desc_item[] = {
 	MK_FLOW_ITEM(CONNTRACK, sizeof(uint32_t)),
 	MK_FLOW_ITEM(PORT_REPRESENTOR, sizeof(struct rte_flow_item_ethdev)),
 	MK_FLOW_ITEM(REPRESENTED_PORT, sizeof(struct rte_flow_item_ethdev)),
+	MK_FLOW_ITEM(L2TPV2, sizeof(struct rte_flow_item_l2tpv2)),
+	MK_FLOW_ITEM(PPP, sizeof(struct rte_flow_item_ppp)),
 };
 
 /** Generate flow_action[] entry. */
diff --git a/lib/ethdev/rte_flow.h b/lib/ethdev/rte_flow.h
index d5bfdaaaf2..2bc825b567 100644
--- a/lib/ethdev/rte_flow.h
+++ b/lib/ethdev/rte_flow.h
@@ -35,6 +35,8 @@
 #include <rte_mbuf_dyn.h>
 #include <rte_meter.h>
 #include <rte_gtp.h>
+#include <rte_l2tpv2.h>
+#include <rte_ppp.h>
 
 #ifdef __cplusplus
 extern "C" {
@@ -635,6 +637,21 @@ enum rte_flow_item_type {
 	 * @see struct rte_flow_item_ethdev
 	 */
 	RTE_FLOW_ITEM_TYPE_REPRESENTED_PORT,
+
+	/**
+	 * Matches L2TPV2 Header.
+	 *
+	 * See struct rte_flow_item_l2tpv2.
+	 */
+	RTE_FLOW_ITEM_TYPE_L2TPV2,
+
+	/**
+	 * Matches PPP Header.
+	 *
+	 * See struct rte_flow_item_ppp.
+	 */
+	RTE_FLOW_ITEM_TYPE_PPP,
+
 };
 
 /**
@@ -1891,6 +1908,55 @@ static const struct rte_flow_item_ethdev rte_flow_item_ethdev_mask = {
 };
 #endif
 
+/**
+ * @warning
+ * @b EXPERIMENTAL: this structure may change without prior notice
+ * RTE_FLOW_ITEM_TYPE_L2TPV2
+ *
+ * Matches L2TPv2 Header
+ */
+struct rte_flow_item_l2tpv2 {
+	struct rte_l2tpv2_combined_msg_hdr hdr;
+};
+
+/** Default mask for RTE_FLOW_ITEM_TYPE_L2TPV2. */
+#ifndef __cplusplus
+static const struct rte_flow_item_l2tpv2 rte_flow_item_l2tpv2_mask = {
+	/*
+	 * flags and version bit mask
+	 * 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0
+	 * T L x x S x O P x x x x V V V V
+	 */
+	.hdr = {
+		.common = {
+			.flags_version = 0xcb0f,
+		},
+	},
+};
+#endif
+
+/**
+ * @warning
+ * @b EXPERIMENTAL: this structure may change without prior notice
+ * RTE_FLOW_ITEM_TYPE_PPP
+ *
+ * Matches PPP Header
+ */
+struct rte_flow_item_ppp {
+	struct rte_ppp_hdr hdr;
+};
+
+/** Default mask for RTE_FLOW_ITEM_TYPE_PPP. */
+#ifndef __cplusplus
+static const struct rte_flow_item_ppp rte_flow_item_ppp_mask = {
+	.hdr = {
+		.addr = 0xff,
+		.ctrl = 0xff,
+		.proto_id = 0xffff,
+	}
+};
+#endif
+
 /**
  * Matching pattern item definition.
  *
diff --git a/lib/net/rte_l2tpv2.h b/lib/net/rte_l2tpv2.h
new file mode 100644
index 0000000000..aea3c689be
--- /dev/null
+++ b/lib/net/rte_l2tpv2.h
@@ -0,0 +1,214 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright 2021 Mellanox Technologies, Ltd
+ */
+
+#ifndef _RTE_L2TPV2_H_
+#define _RTE_L2TPV2_H_
+
+/**
+ * @file
+ *
+ * L2TP header:
+ *  0                   1                   2                   3
+ *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |T|L|x|x|S|x|O|P|x|x|x|x|  Ver  |          Length (opt)         |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |           Tunnel ID           |           Session ID          |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |             Ns (opt)          |             Nr (opt)          |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |      Offset Size (opt)        |    Offset pad... (opt)
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *
+ * The Type (T) bit indicates the type of message. It is set to 0 for a data
+ * message and 1 for a control message.
+ *
+ * If the Length (L) bit is 1, the Length field is present. This bit MUST be
+ * set to 1 for control messages.
+ *
+ * The x bits are reserved for future extensions. All reserved bits MUST
+ * be set to 0 on outgoing messages and ignored on incoming messages.
+ *
+ * If the Sequence (S) bit is set to 1 the Ns and Nr fields are present.
+ * The S bit MUST be set to 1 for control messages.
+ *
+ * If the Offset (O) bit is 1, the Offset Size field is present. The O
+ * bit MUST be set to 0 for control messages.
+ *
+ * If the Priority (P) bit is 1, this data message should receive
+ * preferential treatment in its local queuing and transmission.
+ * The P bit MUST be set to 0 for control messages.
+ *
+ * Ver MUST be 2, indicating the version of the L2TP data message header.
+ *
+ * The Length field indicates the total length of the message in octets.
+ *
+ * Tunnel ID indicates the identifier for the control connection.
+ *
+ * Session ID indicates the identifier for a session within a tunnel.
+ *
+ * Ns indicates the sequence number for this data or control message.
+ *
+ * Nr indicates the sequence number expected in the next control message
+ * to be received.
+ *
+ * The Offset Size field, if present, specifies the number of octets
+ * past the L2TP header at which the payload data is expected to start.
+ * Actual data within the offset padding is undefined. If the offset
+ * field is present, the L2TP header ends after the last octet of the
+ * offset padding.
+ */
+
+#include <stdint.h>
+#include <rte_byteorder.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * L2TPv2 Common Header
+ */
+RTE_STD_C11
+struct rte_l2tpv2_common_hdr {
+	union {
+		rte_be16_t flags_version;
+		struct {
+#if RTE_BYTE_ORDER == RTE_LITTLE_ENDIAN
+			rte_be16_t t:1;		/**< message Type */
+			rte_be16_t l:1;		/**< length option bit*/
+			rte_be16_t res1:2;	/**< reserved */
+			rte_be16_t s:1;		/**< ns/nr option bit*/
+			rte_be16_t res2:1;	/**< reserved */
+			rte_be16_t o:1;		/**< offset option bit*/
+			rte_be16_t p:1;		/**< priority option bit*/
+			rte_be16_t res3:4;	/**< reserved */
+			rte_be16_t ver:4;	/**< protocol version */
+#elif RTE_BYTE_ORDER == RTE_BIG_ENDIAN
+			rte_be16_t ver:4;	/**< protocol version */
+			rte_be16_t res3:4;	/**< reserved */
+			rte_be16_t p:1;		/**< priority option bit*/
+			rte_be16_t o:1;		/**< offset option bit*/
+			rte_be16_t res2:1;	/**< reserved */
+			rte_be16_t s:1;		/**< ns/nr option bit*/
+			rte_be16_t res1:2;	/**< reserved */
+			rte_be16_t l:1;		/**< length option bit*/
+			rte_be16_t t:1;		/**< message Type */
+#endif
+		};
+	};
+};
+
+/*
+ * L2TPv2 message Header contains all options(length, ns, nr,
+ * offset size, offset padding).
+ */
+struct rte_l2tpv2_msg_with_all_options {
+	rte_be16_t length;		/**< length(16) */
+	rte_be16_t tunnel_id;		/**< tunnel id(16) */
+	rte_be16_t session_id;		/**< session id(16) */
+	rte_be16_t ns;			/**< Ns(16) */
+	rte_be16_t nr;			/**< Nr(16) */
+	rte_be16_t offset_size;		/**< offset size(16) */
+	uint8_t   *offset_padding;	/**< offset padding(variable length) */
+};
+
+/*
+ * L2TPv2 message Header contains all options except length(ns, nr,
+ * offset size, offset padding).
+ */
+struct rte_l2tpv2_msg_without_length {
+	rte_be16_t tunnel_id;		/**< tunnel id(16) */
+	rte_be16_t session_id;		/**< session id(16) */
+	rte_be16_t ns;			/**< Ns(16) */
+	rte_be16_t nr;			/**< Nr(16) */
+	rte_be16_t offset_size;		/**< offset size(16) */
+	uint8_t   *offset_padding;	/**< offset padding(variable length) */
+};
+
+/*
+ * L2TPv2 message Header contains all options except ns_nr(length,
+ * offset size, offset padding).
+ * Ns and Nr MUST be toghter.
+ */
+struct rte_l2tpv2_msg_without_ns_nr {
+	rte_be16_t length;		/**< length(16) */
+	rte_be16_t tunnel_id;		/**< tunnel id(16) */
+	rte_be16_t session_id;		/**< session id(16) */
+	rte_be16_t offset_size;		/**< offset size(16) */
+	uint8_t   *offset_padding;	/**< offset padding(variable length) */
+};
+
+/*
+ * L2TPv2 message Header contains all options except ns_nr(length, ns, nr).
+ * offset size and offset padding MUST be toghter.
+ */
+struct rte_l2tpv2_msg_without_offset {
+	rte_be16_t length;		/**< length(16) */
+	rte_be16_t tunnel_id;		/**< tunnel id(16) */
+	rte_be16_t session_id;		/**< session id(16) */
+	rte_be16_t ns;			/**< Ns(16) */
+	rte_be16_t nr;			/**< Nr(16) */
+};
+
+/*
+ * L2TPv2 message Header contains options offset size and offset padding.
+ */
+struct rte_l2tpv2_msg_with_offset {
+	rte_be16_t tunnel_id;		/**< tunnel id(16) */
+	rte_be16_t session_id;		/**< session id(16) */
+	rte_be16_t offset_size;		/**< offset size(16) */
+	uint8_t   *offset_padding;	/**< offset padding(variable length) */
+};
+
+/*
+ * L2TPv2 message Header contains options ns and nr.
+ */
+struct rte_l2tpv2_msg_with_ns_nr {
+	rte_be16_t tunnel_id;		/**< tunnel id(16) */
+	rte_be16_t session_id;		/**< session id(16) */
+	rte_be16_t ns;			/**< Ns(16) */
+	rte_be16_t nr;			/**< Nr(16) */
+};
+
+/*
+ * L2TPv2 message Header contains option length.
+ */
+struct rte_l2tpv2_msg_with_length {
+	rte_be16_t length;		/**< length(16) */
+	rte_be16_t tunnel_id;		/**< tunnel id(16) */
+	rte_be16_t session_id;		/**< session id(16) */
+};
+
+/*
+ * L2TPv2 message Header without all options.
+ */
+struct rte_l2tpv2_msg_without_all_options {
+	rte_be16_t tunnel_id;		/**< tunnel id(16) */
+	rte_be16_t session_id;		/**< session id(16) */
+};
+
+/**
+ * L2TPv2 Combined Message Header Format: Common Header + Options
+ */
+RTE_STD_C11
+struct rte_l2tpv2_combined_msg_hdr {
+	struct rte_l2tpv2_common_hdr common;
+	union {
+		struct rte_l2tpv2_msg_with_all_options type0;
+		struct rte_l2tpv2_msg_without_length type1;
+		struct rte_l2tpv2_msg_without_ns_nr type2;
+		struct rte_l2tpv2_msg_without_offset type3;
+		struct rte_l2tpv2_msg_with_offset type4;
+		struct rte_l2tpv2_msg_with_ns_nr type5;
+		struct rte_l2tpv2_msg_with_length type6;
+		struct rte_l2tpv2_msg_without_all_options type7;
+	};
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RTE_L2TPV2_H_ */
diff --git a/lib/net/rte_ppp.h b/lib/net/rte_ppp.h
new file mode 100644
index 0000000000..9ea633baa7
--- /dev/null
+++ b/lib/net/rte_ppp.h
@@ -0,0 +1,35 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright 2021 Mellanox Technologies, Ltd
+ */
+
+#ifndef _RTE_PPP_H_
+#define _RTE_PPP_H_
+
+/**
+ * @file
+ *
+ * PPP headers definition.
+ *
+ */
+
+#include <stdint.h>
+#include <rte_byteorder.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * PPP Header
+ */
+struct rte_ppp_hdr {
+	uint8_t addr; /**< ppp address(8) */
+	uint8_t ctrl; /**< ppp control(8) */
+	rte_be16_t proto_id; /**< ppp protocol id(16) */
+} __rte_packed;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RTE_PPP_H_ */
-- 
2.25.1


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

* [dpdk-dev] [PATCH v5 2/3] net/iavf: support PPPoL2TPv2oUDP RSS Hash
  2021-10-19  3:08       ` [dpdk-dev] [PATCH v5 0/3] support PPPoL2TPv2oUDP RSS Hash Jie Wang
  2021-10-19  3:08         ` [dpdk-dev] [PATCH v5 1/3] ethdev: support PPP and L2TPV2 procotol Jie Wang
@ 2021-10-19  3:08         ` Jie Wang
  2021-10-20  1:57           ` Xing, Beilei
  2021-10-19  3:08         ` [dpdk-dev] [PATCH v5 3/3] app/testpmd: support L2TPV2 and PPP protocol pattern Jie Wang
  2021-10-20  9:32         ` [dpdk-dev] [PATCH v6 0/3] support PPPoL2TPv2oUDP RSS Hash Jie Wang
  3 siblings, 1 reply; 71+ messages in thread
From: Jie Wang @ 2021-10-19  3:08 UTC (permalink / raw)
  To: dev
  Cc: orika, ferruh.yigit, thomas, andrew.rybchenko, xiaoyun.li,
	stevex.yang, jingjing.wu, beilei.xing, wenjun1.wu, qi.z.zhang,
	Jie Wang

Add support for PPP over L2TPv2 over UDP protocol RSS Hash based
on inner IP src/dst address and TCP/UDP src/dst port.

Patterns are listed below:
eth/ipv4(6)/udp/l2tpv2/ppp/ipv4(6)
eth/ipv4(6)/udp/l2tpv2/ppp/ipv4(6)/udp
eth/ipv4(6)/udp/l2tpv2/ppp/ipv4(6)/tcp

Signed-off-by: Wenjun Wu <wenjun1.wu@intel.com>
Signed-off-by: Jie Wang <jie1x.wang@intel.com>
---
 drivers/net/iavf/iavf_generic_flow.c | 131 +++++++++++++++++++++++++++
 drivers/net/iavf/iavf_generic_flow.h |  15 +++
 drivers/net/iavf/iavf_hash.c         | 108 +++++++++++++++++++++-
 3 files changed, 252 insertions(+), 2 deletions(-)

diff --git a/drivers/net/iavf/iavf_generic_flow.c b/drivers/net/iavf/iavf_generic_flow.c
index b86d99e57d..364904fa02 100644
--- a/drivers/net/iavf/iavf_generic_flow.c
+++ b/drivers/net/iavf/iavf_generic_flow.c
@@ -1611,6 +1611,137 @@ enum rte_flow_item_type iavf_pattern_eth_ipv6_gre_ipv6_udp[] = {
 	RTE_FLOW_ITEM_TYPE_END,
 };
 
+/* PPPoL2TPv2oUDP */
+enum rte_flow_item_type iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv4[] = {
+	RTE_FLOW_ITEM_TYPE_ETH,
+	RTE_FLOW_ITEM_TYPE_IPV4,
+	RTE_FLOW_ITEM_TYPE_UDP,
+	RTE_FLOW_ITEM_TYPE_L2TPV2,
+	RTE_FLOW_ITEM_TYPE_PPP,
+	RTE_FLOW_ITEM_TYPE_IPV4,
+	RTE_FLOW_ITEM_TYPE_END,
+};
+
+enum rte_flow_item_type iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv6[] = {
+	RTE_FLOW_ITEM_TYPE_ETH,
+	RTE_FLOW_ITEM_TYPE_IPV4,
+	RTE_FLOW_ITEM_TYPE_UDP,
+	RTE_FLOW_ITEM_TYPE_L2TPV2,
+	RTE_FLOW_ITEM_TYPE_PPP,
+	RTE_FLOW_ITEM_TYPE_IPV6,
+	RTE_FLOW_ITEM_TYPE_END,
+};
+
+enum rte_flow_item_type iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv4_udp[] = {
+	RTE_FLOW_ITEM_TYPE_ETH,
+	RTE_FLOW_ITEM_TYPE_IPV4,
+	RTE_FLOW_ITEM_TYPE_UDP,
+	RTE_FLOW_ITEM_TYPE_L2TPV2,
+	RTE_FLOW_ITEM_TYPE_PPP,
+	RTE_FLOW_ITEM_TYPE_IPV4,
+	RTE_FLOW_ITEM_TYPE_UDP,
+	RTE_FLOW_ITEM_TYPE_END,
+};
+
+enum rte_flow_item_type iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv4_tcp[] = {
+	RTE_FLOW_ITEM_TYPE_ETH,
+	RTE_FLOW_ITEM_TYPE_IPV4,
+	RTE_FLOW_ITEM_TYPE_UDP,
+	RTE_FLOW_ITEM_TYPE_L2TPV2,
+	RTE_FLOW_ITEM_TYPE_PPP,
+	RTE_FLOW_ITEM_TYPE_IPV4,
+	RTE_FLOW_ITEM_TYPE_TCP,
+	RTE_FLOW_ITEM_TYPE_END,
+};
+
+enum rte_flow_item_type iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv6_udp[] = {
+	RTE_FLOW_ITEM_TYPE_ETH,
+	RTE_FLOW_ITEM_TYPE_IPV4,
+	RTE_FLOW_ITEM_TYPE_UDP,
+	RTE_FLOW_ITEM_TYPE_L2TPV2,
+	RTE_FLOW_ITEM_TYPE_PPP,
+	RTE_FLOW_ITEM_TYPE_IPV6,
+	RTE_FLOW_ITEM_TYPE_UDP,
+	RTE_FLOW_ITEM_TYPE_END,
+};
+
+enum rte_flow_item_type iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv6_tcp[] = {
+	RTE_FLOW_ITEM_TYPE_ETH,
+	RTE_FLOW_ITEM_TYPE_IPV4,
+	RTE_FLOW_ITEM_TYPE_UDP,
+	RTE_FLOW_ITEM_TYPE_L2TPV2,
+	RTE_FLOW_ITEM_TYPE_PPP,
+	RTE_FLOW_ITEM_TYPE_IPV6,
+	RTE_FLOW_ITEM_TYPE_TCP,
+	RTE_FLOW_ITEM_TYPE_END,
+};
+
+enum rte_flow_item_type iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv4[] = {
+	RTE_FLOW_ITEM_TYPE_ETH,
+	RTE_FLOW_ITEM_TYPE_IPV6,
+	RTE_FLOW_ITEM_TYPE_UDP,
+	RTE_FLOW_ITEM_TYPE_L2TPV2,
+	RTE_FLOW_ITEM_TYPE_PPP,
+	RTE_FLOW_ITEM_TYPE_IPV4,
+	RTE_FLOW_ITEM_TYPE_END,
+};
+
+enum rte_flow_item_type iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv6[] = {
+	RTE_FLOW_ITEM_TYPE_ETH,
+	RTE_FLOW_ITEM_TYPE_IPV6,
+	RTE_FLOW_ITEM_TYPE_UDP,
+	RTE_FLOW_ITEM_TYPE_L2TPV2,
+	RTE_FLOW_ITEM_TYPE_PPP,
+	RTE_FLOW_ITEM_TYPE_IPV6,
+	RTE_FLOW_ITEM_TYPE_END,
+};
+
+enum rte_flow_item_type iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv4_udp[] = {
+	RTE_FLOW_ITEM_TYPE_ETH,
+	RTE_FLOW_ITEM_TYPE_IPV6,
+	RTE_FLOW_ITEM_TYPE_UDP,
+	RTE_FLOW_ITEM_TYPE_L2TPV2,
+	RTE_FLOW_ITEM_TYPE_PPP,
+	RTE_FLOW_ITEM_TYPE_IPV4,
+	RTE_FLOW_ITEM_TYPE_UDP,
+	RTE_FLOW_ITEM_TYPE_END,
+};
+
+enum rte_flow_item_type iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv4_tcp[] = {
+	RTE_FLOW_ITEM_TYPE_ETH,
+	RTE_FLOW_ITEM_TYPE_IPV6,
+	RTE_FLOW_ITEM_TYPE_UDP,
+	RTE_FLOW_ITEM_TYPE_L2TPV2,
+	RTE_FLOW_ITEM_TYPE_PPP,
+	RTE_FLOW_ITEM_TYPE_IPV4,
+	RTE_FLOW_ITEM_TYPE_TCP,
+	RTE_FLOW_ITEM_TYPE_END,
+};
+
+enum rte_flow_item_type iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv6_udp[] = {
+	RTE_FLOW_ITEM_TYPE_ETH,
+	RTE_FLOW_ITEM_TYPE_IPV6,
+	RTE_FLOW_ITEM_TYPE_UDP,
+	RTE_FLOW_ITEM_TYPE_L2TPV2,
+	RTE_FLOW_ITEM_TYPE_PPP,
+	RTE_FLOW_ITEM_TYPE_IPV6,
+	RTE_FLOW_ITEM_TYPE_UDP,
+	RTE_FLOW_ITEM_TYPE_END,
+};
+
+enum rte_flow_item_type iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv6_tcp[] = {
+	RTE_FLOW_ITEM_TYPE_ETH,
+	RTE_FLOW_ITEM_TYPE_IPV6,
+	RTE_FLOW_ITEM_TYPE_UDP,
+	RTE_FLOW_ITEM_TYPE_L2TPV2,
+	RTE_FLOW_ITEM_TYPE_PPP,
+	RTE_FLOW_ITEM_TYPE_IPV6,
+	RTE_FLOW_ITEM_TYPE_TCP,
+	RTE_FLOW_ITEM_TYPE_END,
+};
+
+
+
 typedef struct iavf_flow_engine * (*parse_engine_t)(struct iavf_adapter *ad,
 		struct rte_flow *flow,
 		struct iavf_parser_list *parser_list,
diff --git a/drivers/net/iavf/iavf_generic_flow.h b/drivers/net/iavf/iavf_generic_flow.h
index 4794d1fb80..f2b54e1944 100644
--- a/drivers/net/iavf/iavf_generic_flow.h
+++ b/drivers/net/iavf/iavf_generic_flow.h
@@ -410,6 +410,21 @@ extern enum rte_flow_item_type iavf_pattern_eth_ipv6_gre_ipv6_tcp[];
 extern enum rte_flow_item_type iavf_pattern_eth_ipv6_gre_ipv4_udp[];
 extern enum rte_flow_item_type iavf_pattern_eth_ipv6_gre_ipv6_udp[];
 
+/* PPPoL2TPv2oUDP */
+extern enum rte_flow_item_type iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv4[];
+extern enum rte_flow_item_type iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv6[];
+extern enum rte_flow_item_type iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv4_udp[];
+extern enum rte_flow_item_type iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv4_tcp[];
+extern enum rte_flow_item_type iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv6_udp[];
+extern enum rte_flow_item_type iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv6_tcp[];
+extern enum rte_flow_item_type iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv4[];
+extern enum rte_flow_item_type iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv6[];
+extern enum rte_flow_item_type iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv4_udp[];
+extern enum rte_flow_item_type iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv4_tcp[];
+extern enum rte_flow_item_type iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv6_udp[];
+extern enum rte_flow_item_type iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv6_tcp[];
+
+
 extern const struct rte_flow_ops iavf_flow_ops;
 
 /* pattern structure */
diff --git a/drivers/net/iavf/iavf_hash.c b/drivers/net/iavf/iavf_hash.c
index 1f2d3772d1..9e7286861e 100644
--- a/drivers/net/iavf/iavf_hash.c
+++ b/drivers/net/iavf/iavf_hash.c
@@ -34,6 +34,8 @@
 /* the second IP header of GTPoGRE */
 #define IAVF_PHINT_MID_IPV4			BIT_ULL(7)
 #define IAVF_PHINT_MID_IPV6			BIT_ULL(8)
+/* L2TPV2 */
+#define IAVF_PHINT_L2TPV2			BIT_ULL(9)
 
 #define IAVF_PHINT_GTPU_MSK	(IAVF_PHINT_GTPU	| \
 				 IAVF_PHINT_GTPU_EH	| \
@@ -164,6 +166,12 @@ iavf_hash_parse_pattern_action(struct iavf_adapter *ad,
 	VIRTCHNL_PROTO_HDR_ECPRI, \
 	FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_ECPRI_PC_RTC_ID), {BUFF_NOUSED} }
 
+#define proto_hdr_l2tpv2 { \
+	VIRTCHNL_PROTO_HDR_L2TPV2, 0, {BUFF_NOUSED} }
+
+#define proto_hdr_ppp { \
+	VIRTCHNL_PROTO_HDR_PPP, 0, {BUFF_NOUSED} }
+
 #define TUNNEL_LEVEL_OUTER		0
 #define TUNNEL_LEVEL_INNER		1
 
@@ -338,6 +346,52 @@ struct virtchnl_proto_hdrs ipv4_ecpri_tmplt = {
 	TUNNEL_LEVEL_OUTER, 3, {proto_hdr_ipv4, proto_hdr_udp, proto_hdr_ecpri}
 };
 
+struct virtchnl_proto_hdrs udp_l2tpv2_ppp_ipv4_tmplt = {
+	TUNNEL_LEVEL_INNER, 3,
+	{proto_hdr_l2tpv2,
+	 proto_hdr_ppp,
+	 proto_hdr_ipv4}
+};
+
+struct virtchnl_proto_hdrs udp_l2tpv2_ppp_ipv6_tmplt = {
+	TUNNEL_LEVEL_INNER, 3,
+	{proto_hdr_l2tpv2,
+	 proto_hdr_ppp,
+	 proto_hdr_ipv6}
+};
+
+struct virtchnl_proto_hdrs udp_l2tpv2_ppp_ipv4_udp_tmplt = {
+	TUNNEL_LEVEL_INNER, 4,
+	{proto_hdr_l2tpv2,
+	 proto_hdr_ppp,
+	 proto_hdr_ipv4_with_prot,
+	 proto_hdr_udp}
+};
+
+struct virtchnl_proto_hdrs udp_l2tpv2_ppp_ipv4_tcp_tmplt = {
+	TUNNEL_LEVEL_INNER, 4,
+	{proto_hdr_l2tpv2,
+	 proto_hdr_ppp,
+	 proto_hdr_ipv4_with_prot,
+	 proto_hdr_tcp}
+};
+
+struct virtchnl_proto_hdrs udp_l2tpv2_ppp_ipv6_udp_tmplt = {
+	TUNNEL_LEVEL_INNER, 4,
+	{proto_hdr_l2tpv2,
+	 proto_hdr_ppp,
+	 proto_hdr_ipv6_with_prot,
+	 proto_hdr_udp}
+};
+
+struct virtchnl_proto_hdrs udp_l2tpv2_ppp_ipv6_tcp_tmplt = {
+	TUNNEL_LEVEL_INNER, 4,
+	{proto_hdr_l2tpv2,
+	 proto_hdr_ppp,
+	 proto_hdr_ipv6_with_prot,
+	 proto_hdr_tcp}
+};
+
 /* rss type super set */
 
 /* IPv4 outer */
@@ -493,6 +547,13 @@ static struct iavf_pattern_match_item iavf_hash_pattern_list[] = {
 	{iavf_pattern_eth_ipv6_gre_ipv4_tcp,	IAVF_RSS_TYPE_INNER_IPV4_TCP, &inner_ipv4_tcp_tmplt},
 	{iavf_pattern_eth_ipv4_gre_ipv4_udp,	IAVF_RSS_TYPE_INNER_IPV4_UDP, &inner_ipv4_udp_tmplt},
 	{iavf_pattern_eth_ipv6_gre_ipv4_udp,	IAVF_RSS_TYPE_INNER_IPV4_UDP, &inner_ipv4_udp_tmplt},
+	{iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv4,	IAVF_RSS_TYPE_INNER_IPV4,	&udp_l2tpv2_ppp_ipv4_tmplt},
+	{iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv4_udp,	IAVF_RSS_TYPE_INNER_IPV4_UDP,	&udp_l2tpv2_ppp_ipv4_udp_tmplt},
+	{iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv4_tcp,	IAVF_RSS_TYPE_INNER_IPV4_TCP,	&udp_l2tpv2_ppp_ipv4_tcp_tmplt},
+	{iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv4,	IAVF_RSS_TYPE_INNER_IPV4,	&udp_l2tpv2_ppp_ipv4_tmplt},
+	{iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv4_udp,	IAVF_RSS_TYPE_INNER_IPV4_UDP,	&udp_l2tpv2_ppp_ipv4_udp_tmplt},
+	{iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv4_tcp,	IAVF_RSS_TYPE_INNER_IPV4_TCP,	&udp_l2tpv2_ppp_ipv4_tcp_tmplt},
+
 	/* IPv6 */
 	{iavf_pattern_eth_ipv6,				IAVF_RSS_TYPE_OUTER_IPV6,	&outer_ipv6_tmplt},
 	{iavf_pattern_eth_ipv6_frag_ext,		IAVF_RSS_TYPE_OUTER_IPV6_FRAG,	&outer_ipv6_frag_tmplt},
@@ -553,6 +614,13 @@ static struct iavf_pattern_match_item iavf_hash_pattern_list[] = {
 	{iavf_pattern_eth_ipv6_gre_ipv6_tcp,	IAVF_RSS_TYPE_INNER_IPV6_TCP, &inner_ipv6_tcp_tmplt},
 	{iavf_pattern_eth_ipv4_gre_ipv6_udp,	IAVF_RSS_TYPE_INNER_IPV6_UDP, &inner_ipv6_udp_tmplt},
 	{iavf_pattern_eth_ipv6_gre_ipv6_udp,	IAVF_RSS_TYPE_INNER_IPV6_UDP, &inner_ipv6_udp_tmplt},
+	{iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv6,	IAVF_RSS_TYPE_INNER_IPV6,	&udp_l2tpv2_ppp_ipv6_tmplt},
+	{iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv6_udp,	IAVF_RSS_TYPE_INNER_IPV6_UDP,	&udp_l2tpv2_ppp_ipv6_udp_tmplt},
+	{iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv6_tcp,	IAVF_RSS_TYPE_INNER_IPV6_TCP,	&udp_l2tpv2_ppp_ipv6_tcp_tmplt},
+	{iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv6,	IAVF_RSS_TYPE_INNER_IPV6,	&udp_l2tpv2_ppp_ipv6_tmplt},
+	{iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv6_udp,	IAVF_RSS_TYPE_INNER_IPV6_UDP,	&udp_l2tpv2_ppp_ipv6_udp_tmplt},
+	{iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv6_tcp,	IAVF_RSS_TYPE_INNER_IPV6_TCP,	&udp_l2tpv2_ppp_ipv6_tcp_tmplt},
+
 };
 
 static struct iavf_flow_engine iavf_hash_engine = {
@@ -687,13 +755,17 @@ iavf_hash_parse_pattern(const struct rte_flow_item pattern[], uint64_t *phint,
 
 		switch (item->type) {
 		case RTE_FLOW_ITEM_TYPE_IPV4:
-			if (!(*phint & IAVF_PHINT_GTPU_MSK) && !(*phint & IAVF_PHINT_GRE))
+			if (!(*phint & IAVF_PHINT_GTPU_MSK) &&
+			    !(*phint & IAVF_PHINT_GRE) &&
+			    !(*phint & IAVF_PHINT_L2TPV2))
 				*phint |= IAVF_PHINT_OUTER_IPV4;
 			if ((*phint & IAVF_PHINT_GRE) && !(*phint & IAVF_PHINT_GTPU_MSK))
 				*phint |= IAVF_PHINT_MID_IPV4;
 			break;
 		case RTE_FLOW_ITEM_TYPE_IPV6:
-			if (!(*phint & IAVF_PHINT_GTPU_MSK) && !(*phint & IAVF_PHINT_GRE))
+			if (!(*phint & IAVF_PHINT_GTPU_MSK) &&
+			    !(*phint & IAVF_PHINT_GRE) &&
+			    !(*phint & IAVF_PHINT_L2TPV2))
 				*phint |= IAVF_PHINT_OUTER_IPV6;
 			if ((*phint & IAVF_PHINT_GRE) && !(*phint & IAVF_PHINT_GTPU_MSK))
 				*phint |= IAVF_PHINT_MID_IPV6;
@@ -728,6 +800,10 @@ iavf_hash_parse_pattern(const struct rte_flow_item pattern[], uint64_t *phint,
 			break;
 		case RTE_FLOW_ITEM_TYPE_GRE:
 			*phint |= IAVF_PHINT_GRE;
+			break;
+		case RTE_FLOW_ITEM_TYPE_L2TPV2:
+			*phint |= IAVF_PHINT_L2TPV2;
+			break;
 		default:
 			break;
 		}
@@ -1050,12 +1126,40 @@ iavf_refine_proto_hdrs_by_pattern(struct virtchnl_proto_hdrs *proto_hdrs,
 	proto_hdrs->tunnel_level = tun_lvl;
 }
 
+static void
+iavf_refine_proto_hdrs_l2tpv2(struct virtchnl_proto_hdrs *proto_hdrs,
+			      uint64_t phint)
+{
+	struct virtchnl_proto_hdr *hdr1;
+	int i;
+
+	if (!(phint & IAVF_PHINT_L2TPV2))
+		return;
+
+	if (proto_hdrs->tunnel_level == TUNNEL_LEVEL_INNER) {
+		/* shift headers layer */
+		for (i = proto_hdrs->count - 1 + 1; i > 0; i--)
+			proto_hdrs->proto_hdr[i] = proto_hdrs->proto_hdr[i - 1];
+
+		/* adding outer ip header at layer 0 */
+		hdr1 = &proto_hdrs->proto_hdr[0];
+		hdr1->field_selector = 0;
+		proto_hdrs->count++;
+		proto_hdrs->tunnel_level = TUNNEL_LEVEL_OUTER;
+		if (phint & IAVF_PHINT_OUTER_IPV4)
+			VIRTCHNL_SET_PROTO_HDR_TYPE(hdr1, IPV4);
+		else if (phint & IAVF_PHINT_OUTER_IPV6)
+			VIRTCHNL_SET_PROTO_HDR_TYPE(hdr1, IPV6);
+	}
+}
+
 static void iavf_refine_proto_hdrs(struct virtchnl_proto_hdrs *proto_hdrs,
 				   uint64_t rss_type, uint64_t phint)
 {
 	iavf_refine_proto_hdrs_l234(proto_hdrs, rss_type);
 	iavf_refine_proto_hdrs_by_pattern(proto_hdrs, phint);
 	iavf_refine_proto_hdrs_gtpu(proto_hdrs, rss_type);
+	iavf_refine_proto_hdrs_l2tpv2(proto_hdrs, phint);
 }
 
 static uint64_t invalid_rss_comb[] = {
-- 
2.25.1


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

* [dpdk-dev] [PATCH v5 3/3] app/testpmd: support L2TPV2 and PPP protocol pattern
  2021-10-19  3:08       ` [dpdk-dev] [PATCH v5 0/3] support PPPoL2TPv2oUDP RSS Hash Jie Wang
  2021-10-19  3:08         ` [dpdk-dev] [PATCH v5 1/3] ethdev: support PPP and L2TPV2 procotol Jie Wang
  2021-10-19  3:08         ` [dpdk-dev] [PATCH v5 2/3] net/iavf: support PPPoL2TPv2oUDP RSS Hash Jie Wang
@ 2021-10-19  3:08         ` Jie Wang
  2021-10-19  9:41           ` Ferruh Yigit
  2021-10-20  9:32         ` [dpdk-dev] [PATCH v6 0/3] support PPPoL2TPv2oUDP RSS Hash Jie Wang
  3 siblings, 1 reply; 71+ messages in thread
From: Jie Wang @ 2021-10-19  3:08 UTC (permalink / raw)
  To: dev
  Cc: orika, ferruh.yigit, thomas, andrew.rybchenko, xiaoyun.li,
	stevex.yang, jingjing.wu, beilei.xing, wenjun1.wu, qi.z.zhang,
	Jie Wang

Add support for test-pmd to parse protocol pattern L2TPv2 and PPP.

Signed-off-by: Wenjun Wu <wenjun1.wu@intel.com>
Signed-off-by: Jie Wang <jie1x.wang@intel.com>
---
 app/test-pmd/cmdline_flow.c | 251 ++++++++++++++++++++++++++++++++++++
 1 file changed, 251 insertions(+)

diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
index a90822b660..c1046e3e28 100644
--- a/app/test-pmd/cmdline_flow.c
+++ b/app/test-pmd/cmdline_flow.c
@@ -310,6 +310,23 @@ enum index {
 	ITEM_PORT_REPRESENTOR_PORT_ID,
 	ITEM_REPRESENTED_PORT,
 	ITEM_REPRESENTED_PORT_ETHDEV_PORT_ID,
+	ITEM_L2TPV2,
+	ITEM_L2TPV2_COMMON,
+	ITEM_L2TPV2_COMMON_TYPE,
+	ITEM_L2TPV2_COMMON_TYPE_DATA_L,
+	ITEM_L2TPV2_COMMON_TYPE_CTRL,
+	ITEM_L2TPV2_MSG_DATA_L_LENGTH,
+	ITEM_L2TPV2_MSG_DATA_L_TUNNEL_ID,
+	ITEM_L2TPV2_MSG_DATA_L_SESSION_ID,
+	ITEM_L2TPV2_MSG_CTRL_LENGTH,
+	ITEM_L2TPV2_MSG_CTRL_TUNNEL_ID,
+	ITEM_L2TPV2_MSG_CTRL_SESSION_ID,
+	ITEM_L2TPV2_MSG_CTRL_NS,
+	ITEM_L2TPV2_MSG_CTRL_NR,
+	ITEM_PPP,
+	ITEM_PPP_ADDR,
+	ITEM_PPP_CTRL,
+	ITEM_PPP_PROTO_ID,
 
 	/* Validate/create actions. */
 	ACTIONS,
@@ -1018,6 +1035,8 @@ static const enum index next_item[] = {
 	ITEM_CONNTRACK,
 	ITEM_PORT_REPRESENTOR,
 	ITEM_REPRESENTED_PORT,
+	ITEM_L2TPV2,
+	ITEM_PPP,
 	END_SET,
 	ZERO,
 };
@@ -1398,6 +1417,31 @@ static const enum index item_represented_port[] = {
 	ZERO,
 };
 
+static const enum index item_l2tpv2[] = {
+	ITEM_L2TPV2_COMMON,
+	ITEM_NEXT,
+	ZERO,
+};
+
+static const enum index item_l2tpv2_common[] = {
+	ITEM_L2TPV2_COMMON_TYPE,
+	ZERO,
+};
+
+static const enum index item_l2tpv2_common_type[] = {
+	ITEM_L2TPV2_COMMON_TYPE_DATA_L,
+	ITEM_L2TPV2_COMMON_TYPE_CTRL,
+	ZERO,
+};
+
+static const enum index item_ppp[] = {
+	ITEM_PPP_ADDR,
+	ITEM_PPP_CTRL,
+	ITEM_PPP_PROTO_ID,
+	ITEM_NEXT,
+	ZERO,
+};
+
 static const enum index next_action[] = {
 	ACTION_END,
 	ACTION_VOID,
@@ -1781,6 +1825,9 @@ static int parse_vc_conf(struct context *, const struct token *,
 static int parse_vc_item_ecpri_type(struct context *, const struct token *,
 				    const char *, unsigned int,
 				    void *, unsigned int);
+static int parse_vc_item_l2tpv2_type(struct context *, const struct token *,
+				    const char *, unsigned int,
+				    void *, unsigned int);
 static int parse_vc_action_meter_color_type(struct context *,
 					const struct token *,
 					const char *, unsigned int, void *,
@@ -3682,6 +3729,153 @@ static const struct token token_list[] = {
 			     item_param),
 		.args = ARGS(ARGS_ENTRY(struct rte_flow_item_ethdev, port_id)),
 	},
+	[ITEM_L2TPV2] = {
+		.name = "l2tpv2",
+		.help = "match l2tpv2 header",
+		.priv = PRIV_ITEM(L2TPV2, sizeof(struct rte_flow_item_l2tpv2)),
+		.next = NEXT(item_l2tpv2),
+		.call = parse_vc,
+	},
+	[ITEM_L2TPV2_COMMON] = {
+		.name = "common",
+		.help = "l2tpv2 common header",
+		.next = NEXT(item_l2tpv2_common),
+	},
+	[ITEM_L2TPV2_COMMON_TYPE] = {
+		.name = "type",
+		.help = "type of common header",
+		.next = NEXT(item_l2tpv2_common_type),
+		.args = ARGS(ARG_ENTRY_HTON(struct rte_flow_item_l2tpv2)),
+	},
+	[ITEM_L2TPV2_COMMON_TYPE_DATA_L] = {
+		.name = "data_l",
+		.help = "Type #6: data message with length option",
+		.next = NEXT(NEXT_ENTRY(ITEM_L2TPV2_MSG_DATA_L_LENGTH,
+					ITEM_L2TPV2_MSG_DATA_L_TUNNEL_ID,
+					ITEM_L2TPV2_MSG_DATA_L_SESSION_ID,
+					ITEM_NEXT)),
+		.call = parse_vc_item_l2tpv2_type,
+	},
+	[ITEM_L2TPV2_MSG_DATA_L_LENGTH] = {
+		.name = "length",
+		.help = "message length",
+		.next = NEXT(NEXT_ENTRY(ITEM_L2TPV2_MSG_DATA_L_LENGTH,
+					ITEM_L2TPV2_COMMON, ITEM_NEXT),
+			     NEXT_ENTRY(COMMON_UNSIGNED),
+			     item_param),
+		.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2,
+					     hdr.type6.length)),
+	},
+	[ITEM_L2TPV2_MSG_DATA_L_TUNNEL_ID] = {
+		.name = "tunnel_id",
+		.help = "tunnel identifier",
+		.next = NEXT(NEXT_ENTRY(ITEM_L2TPV2_MSG_DATA_L_TUNNEL_ID,
+					ITEM_L2TPV2_COMMON, ITEM_NEXT),
+			     NEXT_ENTRY(COMMON_UNSIGNED),
+			     item_param),
+		.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2,
+					     hdr.type6.tunnel_id)),
+	},
+	[ITEM_L2TPV2_MSG_DATA_L_SESSION_ID] = {
+		.name = "session_id",
+		.help = "session identifier",
+		.next = NEXT(NEXT_ENTRY(ITEM_L2TPV2_MSG_DATA_L_SESSION_ID,
+					ITEM_L2TPV2_COMMON, ITEM_NEXT),
+			     NEXT_ENTRY(COMMON_UNSIGNED),
+			     item_param),
+		.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2,
+					     hdr.type6.session_id)),
+	},
+	[ITEM_L2TPV2_COMMON_TYPE_CTRL] = {
+		.name = "control",
+		.help = "Type #3: conrtol message contains length, ns, nr options",
+		.next = NEXT(NEXT_ENTRY(ITEM_L2TPV2_MSG_CTRL_LENGTH,
+					ITEM_L2TPV2_MSG_CTRL_TUNNEL_ID,
+					ITEM_L2TPV2_MSG_CTRL_SESSION_ID,
+					ITEM_L2TPV2_MSG_CTRL_NS,
+					ITEM_L2TPV2_MSG_CTRL_NR,
+					ITEM_NEXT)),
+		.call = parse_vc_item_l2tpv2_type,
+	},
+	[ITEM_L2TPV2_MSG_CTRL_LENGTH] = {
+		.name = "length",
+		.help = "message length",
+		.next = NEXT(NEXT_ENTRY(ITEM_L2TPV2_MSG_CTRL_LENGTH,
+					ITEM_L2TPV2_COMMON, ITEM_NEXT),
+			     NEXT_ENTRY(COMMON_UNSIGNED),
+			     item_param),
+		.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2,
+					     hdr.type3.length)),
+	},
+	[ITEM_L2TPV2_MSG_CTRL_TUNNEL_ID] = {
+		.name = "tunnel_id",
+		.help = "tunnel identifier",
+		.next = NEXT(NEXT_ENTRY(ITEM_L2TPV2_MSG_CTRL_TUNNEL_ID,
+					ITEM_L2TPV2_COMMON, ITEM_NEXT),
+			     NEXT_ENTRY(COMMON_UNSIGNED),
+			     item_param),
+		.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2,
+					     hdr.type3.tunnel_id)),
+	},
+	[ITEM_L2TPV2_MSG_CTRL_SESSION_ID] = {
+		.name = "session_id",
+		.help = "session identifier",
+		.next = NEXT(NEXT_ENTRY(ITEM_L2TPV2_MSG_CTRL_SESSION_ID,
+					ITEM_L2TPV2_COMMON, ITEM_NEXT),
+			     NEXT_ENTRY(COMMON_UNSIGNED),
+			     item_param),
+		.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2,
+					     hdr.type3.session_id)),
+	},
+	[ITEM_L2TPV2_MSG_CTRL_NS] = {
+		.name = "ns",
+		.help = "sequence number for message",
+		.next = NEXT(NEXT_ENTRY(ITEM_L2TPV2_MSG_CTRL_NS,
+					ITEM_L2TPV2_COMMON, ITEM_NEXT),
+			     NEXT_ENTRY(COMMON_UNSIGNED),
+			     item_param),
+		.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2,
+					     hdr.type3.ns)),
+	},
+	[ITEM_L2TPV2_MSG_CTRL_NR] = {
+		.name = "nr",
+		.help = "sequence number for next receive message",
+		.next = NEXT(NEXT_ENTRY(ITEM_L2TPV2_MSG_CTRL_NS,
+					ITEM_L2TPV2_COMMON, ITEM_NEXT),
+			     NEXT_ENTRY(COMMON_UNSIGNED),
+			     item_param),
+		.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2,
+					     hdr.type3.nr)),
+	},
+	[ITEM_PPP] = {
+		.name = "ppp",
+		.help = "match ppp header",
+		.priv = PRIV_ITEM(PPP, sizeof(struct rte_flow_item_ppp)),
+		.next = NEXT(item_ppp),
+		.call = parse_vc,
+	},
+	[ITEM_PPP_ADDR] = {
+		.name = "addr",
+		.help = "ppp address",
+		.next = NEXT(item_ppp, NEXT_ENTRY(COMMON_UNSIGNED),
+			     item_param),
+		.args = ARGS(ARGS_ENTRY(struct rte_flow_item_ppp, hdr.addr)),
+	},
+	[ITEM_PPP_CTRL] = {
+		.name = "ctrl",
+		.help = "ppp control",
+		.next = NEXT(item_ppp, NEXT_ENTRY(COMMON_UNSIGNED),
+			     item_param),
+		.args = ARGS(ARGS_ENTRY(struct rte_flow_item_ppp, hdr.ctrl)),
+	},
+	[ITEM_PPP_PROTO_ID] = {
+		.name = "proto_id",
+		.help = "ppp protocol id",
+		.next = NEXT(item_ppp, NEXT_ENTRY(COMMON_UNSIGNED),
+			     item_param),
+		.args = ARGS(ARGS_ENTRY(struct rte_flow_item_ppp,
+					hdr.proto_id)),
+	},
 	/* Validate/create actions. */
 	[ACTIONS] = {
 		.name = "actions",
@@ -5569,6 +5763,57 @@ parse_vc_item_ecpri_type(struct context *ctx, const struct token *token,
 	return len;
 }
 
+/** Parse L2TPV2 common header type field. */
+static int
+parse_vc_item_l2tpv2_type(struct context *ctx, const struct token *token,
+			 const char *str, unsigned int len,
+			 void *buf, unsigned int size)
+{
+	struct rte_flow_item_l2tpv2 *l2tpv2;
+	struct rte_flow_item_l2tpv2 *l2tpv2_mask;
+	struct rte_flow_item *item;
+	uint32_t data_size;
+	uint8_t msg_type = 0;
+	struct buffer *out = buf;
+	const struct arg *arg;
+
+	(void)size;
+	/* Token name must match. */
+	if (parse_default(ctx, token, str, len, NULL, 0) < 0)
+		return -1;
+	switch (ctx->curr) {
+	case ITEM_L2TPV2_COMMON_TYPE_DATA_L:
+		msg_type |= 0x4000;
+		break;
+	case ITEM_L2TPV2_COMMON_TYPE_CTRL:
+		msg_type |= 0xC800;
+		break;
+	default:
+		return -1;
+	}
+	if (!ctx->object)
+		return len;
+	arg = pop_args(ctx);
+	if (!arg)
+		return -1;
+	l2tpv2 = (struct rte_flow_item_l2tpv2 *)out->args.vc.data;
+	l2tpv2->hdr.common.flags_version |= msg_type;
+	data_size = ctx->objdata / 3; /* spec, last, mask */
+	l2tpv2_mask = (struct rte_flow_item_l2tpv2 *)(out->args.vc.data +
+						    (data_size * 2));
+	l2tpv2_mask->hdr.common.flags_version = 0xFFFF;
+	if (arg->hton) {
+		l2tpv2->hdr.common.flags_version =
+			rte_cpu_to_be_16(l2tpv2->hdr.common.flags_version);
+		l2tpv2_mask->hdr.common.flags_version =
+		    rte_cpu_to_be_16(l2tpv2_mask->hdr.common.flags_version);
+	}
+	item = &out->args.vc.pattern[out->args.vc.pattern_n - 1];
+	item->spec = l2tpv2;
+	item->mask = l2tpv2_mask;
+	return len;
+}
+
 /** Parse meter color action type. */
 static int
 parse_vc_action_meter_color_type(struct context *ctx, const struct token *token,
@@ -8461,6 +8706,12 @@ flow_item_default_mask(const struct rte_flow_item *item)
 	case RTE_FLOW_ITEM_TYPE_REPRESENTED_PORT:
 		mask = &rte_flow_item_ethdev_mask;
 		break;
+	case RTE_FLOW_ITEM_TYPE_L2TPV2:
+		mask = &rte_flow_item_l2tpv2_mask;
+		break;
+	case RTE_FLOW_ITEM_TYPE_PPP:
+		mask = &rte_flow_item_ppp_mask;
+		break;
 	default:
 		break;
 	}
-- 
2.25.1


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

* Re: [dpdk-dev] [PATCH v5 1/3] ethdev: support PPP and L2TPV2 procotol
  2021-10-19  3:08         ` [dpdk-dev] [PATCH v5 1/3] ethdev: support PPP and L2TPV2 procotol Jie Wang
@ 2021-10-19  6:17           ` Ori Kam
  2021-10-19 10:30           ` Ferruh Yigit
  1 sibling, 0 replies; 71+ messages in thread
From: Ori Kam @ 2021-10-19  6:17 UTC (permalink / raw)
  To: Jie Wang, dev
  Cc: ferruh.yigit, NBU-Contact-Thomas Monjalon, andrew.rybchenko,
	xiaoyun.li, stevex.yang, jingjing.wu, beilei.xing, wenjun1.wu,
	qi.z.zhang

Hi Jie,

> -----Original Message-----
> From: Jie Wang <jie1x.wang@intel.com>
> Sent: Tuesday, October 19, 2021 6:08 AM
> Subject: [PATCH v5 1/3] ethdev: support PPP and L2TPV2 procotol
> 
> Added flow pattern items and header formats of L2TPv2 and PPP.
> 
> Signed-off-by: Wenjun Wu <wenjun1.wu@intel.com>
> Signed-off-by: Jie Wang <jie1x.wang@intel.com>
> ---

Acked-by: Ori Kam <orika@nvidia.com>
Best,
Ori

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

* Re: [dpdk-dev] [PATCH v5 3/3] app/testpmd: support L2TPV2 and PPP protocol pattern
  2021-10-19  3:08         ` [dpdk-dev] [PATCH v5 3/3] app/testpmd: support L2TPV2 and PPP protocol pattern Jie Wang
@ 2021-10-19  9:41           ` Ferruh Yigit
  0 siblings, 0 replies; 71+ messages in thread
From: Ferruh Yigit @ 2021-10-19  9:41 UTC (permalink / raw)
  To: Jie Wang, dev
  Cc: orika, thomas, andrew.rybchenko, xiaoyun.li, stevex.yang,
	jingjing.wu, beilei.xing, wenjun1.wu, qi.z.zhang

On 10/19/2021 4:08 AM, Jie Wang wrote:
> Add support for test-pmd to parse protocol pattern L2TPv2 and PPP.
> 
> Signed-off-by: Wenjun Wu<wenjun1.wu@intel.com>
> Signed-off-by: Jie Wang<jie1x.wang@intel.com>
> ---
>   app/test-pmd/cmdline_flow.c | 251 ++++++++++++++++++++++++++++++++++++
>   1 file changed, 251 insertions(+)

Hi Jie,

Can you please put some samples of the new supported commands in the
'testpmd_funcs.rst' file in "Flow rules management" section, as other
existing samples in the document (at the end of the section)?

Thanks,
ferruh

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

* Re: [dpdk-dev] [PATCH v5 1/3] ethdev: support PPP and L2TPV2 procotol
  2021-10-19  3:08         ` [dpdk-dev] [PATCH v5 1/3] ethdev: support PPP and L2TPV2 procotol Jie Wang
  2021-10-19  6:17           ` Ori Kam
@ 2021-10-19 10:30           ` Ferruh Yigit
  1 sibling, 0 replies; 71+ messages in thread
From: Ferruh Yigit @ 2021-10-19 10:30 UTC (permalink / raw)
  To: Jie Wang, dev
  Cc: orika, thomas, andrew.rybchenko, xiaoyun.li, stevex.yang,
	jingjing.wu, beilei.xing, wenjun1.wu, qi.z.zhang

On 10/19/2021 4:08 AM, Jie Wang wrote:
> Added flow pattern items and header formats of L2TPv2 and PPP.
> 
> Signed-off-by: Wenjun Wu<wenjun1.wu@intel.com>
> Signed-off-by: Jie Wang<jie1x.wang@intel.com>
> ---
>   doc/guides/prog_guide/rte_flow.rst     |  25 +++
>   doc/guides/rel_notes/release_21_11.rst |   4 +
>   lib/ethdev/rte_flow.c                  |   2 +
>   lib/ethdev/rte_flow.h                  |  66 ++++++++
>   lib/net/rte_l2tpv2.h                   | 214 +++++++++++++++++++++++++
>   lib/net/rte_ppp.h                      |  35 ++++
>   6 files changed, 346 insertions(+)
>   create mode 100644 lib/net/rte_l2tpv2.h
>   create mode 100644 lib/net/rte_ppp.h

You need to add these new header in the 'net' lib to the 'lib/net/meson.build',
'headers' variable, so that headers will be installed.

And you may need to update 'doc/api/doxy-api-index.md', '**layers**' with new
headers so that new header will be in the API documentation.
This made me recognize that not all comments are doxygen comments in the header
files, can you please double check? You can generate API doc and verify output.

Thanks,
ferruh

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

* Re: [dpdk-dev] [PATCH v5 2/3] net/iavf: support PPPoL2TPv2oUDP RSS Hash
  2021-10-19  3:08         ` [dpdk-dev] [PATCH v5 2/3] net/iavf: support PPPoL2TPv2oUDP RSS Hash Jie Wang
@ 2021-10-20  1:57           ` Xing, Beilei
  0 siblings, 0 replies; 71+ messages in thread
From: Xing, Beilei @ 2021-10-20  1:57 UTC (permalink / raw)
  To: Wang, Jie1X, dev
  Cc: orika, Yigit, Ferruh, thomas, andrew.rybchenko, Li, Xiaoyun,
	Yang, SteveX, Wu,  Jingjing, Wu, Wenjun1, Zhang, Qi Z



> -----Original Message-----
> From: Wang, Jie1X <jie1x.wang@intel.com>
> Sent: Tuesday, October 19, 2021 11:08 AM
> To: dev@dpdk.org
> Cc: orika@nvidia.com; Yigit, Ferruh <ferruh.yigit@intel.com>;
> thomas@monjalon.net; andrew.rybchenko@oktetlabs.ru; Li, Xiaoyun
> <xiaoyun.li@intel.com>; Yang, SteveX <stevex.yang@intel.com>; Wu, Jingjing
> <jingjing.wu@intel.com>; Xing, Beilei <beilei.xing@intel.com>; Wu, Wenjun1
> <wenjun1.wu@intel.com>; Zhang, Qi Z <qi.z.zhang@intel.com>; Wang, Jie1X
> <jie1x.wang@intel.com>
> Subject: [PATCH v5 2/3] net/iavf: support PPPoL2TPv2oUDP RSS Hash
> 
> Add support for PPP over L2TPv2 over UDP protocol RSS Hash based on inner
> IP src/dst address and TCP/UDP src/dst port.
> 
> Patterns are listed below:
> eth/ipv4(6)/udp/l2tpv2/ppp/ipv4(6)
> eth/ipv4(6)/udp/l2tpv2/ppp/ipv4(6)/udp
> eth/ipv4(6)/udp/l2tpv2/ppp/ipv4(6)/tcp
> 
> Signed-off-by: Wenjun Wu <wenjun1.wu@intel.com>
> Signed-off-by: Jie Wang <jie1x.wang@intel.com>
> ---
>  drivers/net/iavf/iavf_generic_flow.c | 131 +++++++++++++++++++++++++++
> drivers/net/iavf/iavf_generic_flow.h |  15 +++
>  drivers/net/iavf/iavf_hash.c         | 108 +++++++++++++++++++++-
>  3 files changed, 252 insertions(+), 2 deletions(-)
> 

Please also update the release notes.

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

* [dpdk-dev] [PATCH v6 0/3] support PPPoL2TPv2oUDP RSS Hash
  2021-10-19  3:08       ` [dpdk-dev] [PATCH v5 0/3] support PPPoL2TPv2oUDP RSS Hash Jie Wang
                           ` (2 preceding siblings ...)
  2021-10-19  3:08         ` [dpdk-dev] [PATCH v5 3/3] app/testpmd: support L2TPV2 and PPP protocol pattern Jie Wang
@ 2021-10-20  9:32         ` Jie Wang
  2021-10-20  9:32           ` [dpdk-dev] [PATCH v6 1/3] ethdev: support PPP and L2TPV2 procotol Jie Wang
                             ` (3 more replies)
  3 siblings, 4 replies; 71+ messages in thread
From: Jie Wang @ 2021-10-20  9:32 UTC (permalink / raw)
  To: dev
  Cc: orika, ferruh.yigit, thomas, andrew.rybchenko, xiaoyun.li,
	stevex.yang, jingjing.wu, beilei.xing, wenjun1.wu, qi.z.zhang,
	Jie Wang

Support IAVF PPPoL2TPv2oUDP RSS Hash. Required to distribute packets
based on inner IP src+dest address and TCP/UDP src+dest port.

---
v6:
 * update release notes.
 * update lib/net/meson.build.
 * update testpmd_funcs.rst.
 * update doxygen comments in header files.
 * update doc/api/doxy-api-index.md.

v5: update release notes.
v4:
 * update commit log.
 * redefine PPP protocol header.
 * delete l2tpv2_encap.
v3:
 * add testpmd match ppp and l2tpv2 protocol header fields value.
 * add the code of l2tpv2_encap.
 * update the title of ethdev patch and adjust the position of
   the added code.

v2:
 * update the rte_flow.rst and release notes.
 * update l2tpv2 header format.

Jie Wang (3):
  ethdev: support PPP and L2TPV2 procotol
  net/iavf: support PPPoL2TPv2oUDP RSS Hash
  app/testpmd: support L2TPV2 and PPP protocol pattern

 app/test-pmd/cmdline_flow.c                 | 251 ++++++++++++++++++++
 doc/api/doxy-api-index.md                   |   2 +
 doc/guides/prog_guide/rte_flow.rst          |  25 ++
 doc/guides/rel_notes/release_21_11.rst      |   5 +
 doc/guides/testpmd_app_ug/testpmd_funcs.rst |  28 +++
 drivers/net/iavf/iavf_generic_flow.c        | 131 ++++++++++
 drivers/net/iavf/iavf_generic_flow.h        |  15 ++
 drivers/net/iavf/iavf_hash.c                | 108 ++++++++-
 lib/ethdev/rte_flow.c                       |   2 +
 lib/ethdev/rte_flow.h                       |  66 +++++
 lib/net/meson.build                         |   2 +
 lib/net/rte_l2tpv2.h                        | 234 ++++++++++++++++++
 lib/net/rte_ppp.h                           |  35 +++
 13 files changed, 902 insertions(+), 2 deletions(-)
 create mode 100644 lib/net/rte_l2tpv2.h
 create mode 100644 lib/net/rte_ppp.h

-- 
2.25.1


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

* [dpdk-dev] [PATCH v6 1/3] ethdev: support PPP and L2TPV2 procotol
  2021-10-20  9:32         ` [dpdk-dev] [PATCH v6 0/3] support PPPoL2TPv2oUDP RSS Hash Jie Wang
@ 2021-10-20  9:32           ` Jie Wang
  2021-10-20  9:53             ` Andrew Rybchenko
  2021-10-20  9:32           ` [dpdk-dev] [PATCH v6 2/3] net/iavf: support PPPoL2TPv2oUDP RSS Hash Jie Wang
                             ` (2 subsequent siblings)
  3 siblings, 1 reply; 71+ messages in thread
From: Jie Wang @ 2021-10-20  9:32 UTC (permalink / raw)
  To: dev
  Cc: orika, ferruh.yigit, thomas, andrew.rybchenko, xiaoyun.li,
	stevex.yang, jingjing.wu, beilei.xing, wenjun1.wu, qi.z.zhang,
	Jie Wang

Added flow pattern items and header formats of L2TPv2 and PPP.

Signed-off-by: Wenjun Wu <wenjun1.wu@intel.com>
Signed-off-by: Jie Wang <jie1x.wang@intel.com>
---
 doc/api/doxy-api-index.md                   |   2 +
 doc/guides/prog_guide/rte_flow.rst          |  25 +++
 doc/guides/rel_notes/release_21_11.rst      |   5 +
 doc/guides/testpmd_app_ug/testpmd_funcs.rst |  28 +++
 lib/ethdev/rte_flow.c                       |   2 +
 lib/ethdev/rte_flow.h                       |  66 ++++++
 lib/net/meson.build                         |   2 +
 lib/net/rte_l2tpv2.h                        | 234 ++++++++++++++++++++
 lib/net/rte_ppp.h                           |  35 +++
 9 files changed, 399 insertions(+)
 create mode 100644 lib/net/rte_l2tpv2.h
 create mode 100644 lib/net/rte_ppp.h

diff --git a/doc/api/doxy-api-index.md b/doc/api/doxy-api-index.md
index 1992107a03..43b64d06c1 100644
--- a/doc/api/doxy-api-index.md
+++ b/doc/api/doxy-api-index.md
@@ -121,6 +121,8 @@ The public API headers are grouped by topics:
   [VXLAN]              (@ref rte_vxlan.h),
   [Geneve]             (@ref rte_geneve.h),
   [eCPRI]              (@ref rte_ecpri.h)
+  [L2TPV2]             (@ref rte_l2tpv2.h)
+  [PPP]                (@ref rte_ppp.h)
 
 - **QoS**:
   [metering]           (@ref rte_meter.h),
diff --git a/doc/guides/prog_guide/rte_flow.rst b/doc/guides/prog_guide/rte_flow.rst
index fa05fe0845..6277c641ef 100644
--- a/doc/guides/prog_guide/rte_flow.rst
+++ b/doc/guides/prog_guide/rte_flow.rst
@@ -1548,6 +1548,31 @@ This item is meant to use the same structure as `Item: PORT_REPRESENTOR`_.
 
 See also `Action: REPRESENTED_PORT`_.
 
+Item: ``L2TPV2``
+^^^^^^^^^^^^^^^^^^^
+
+Matches a L2TPv2 header.
+
+- ``flags_version``: flags(12b), version(4b).
+- ``length``: total length of the message.
+- ``tunnel_id``: identifier for the control connection.
+- ``session_id``: identifier for a session within a tunnel.
+- ``ns``: sequence number for this date or control message.
+- ``nr``: sequence number expected in the next control message to be received.
+- ``offset_size``: offset of payload data.
+- ``offset_padding``: offset padding, variable length.
+- Default ``mask`` matches flags_version only.
+
+Item: ``PPP``
+^^^^^^^^^^^^^^^^^^^
+
+Matches a PPP header.
+
+- ``addr``: ppp address.
+- ``ctrl``: ppp control.
+- ``proto_id``: ppp protocol identifier.
+- Default ``mask`` matches addr, ctrl, proto_id.
+
 Actions
 ~~~~~~~
 
diff --git a/doc/guides/rel_notes/release_21_11.rst b/doc/guides/rel_notes/release_21_11.rst
index c5f76081e5..9fea43ece7 100644
--- a/doc/guides/rel_notes/release_21_11.rst
+++ b/doc/guides/rel_notes/release_21_11.rst
@@ -98,6 +98,10 @@ New Features
 
   Added an ethdev API which can help users get device configuration.
 
+* **Added L2TPV2 and PPP protocol support in rte_flow.**
+
+  Added flow pattern items and header formats of L2TPv2 and PPP protocol.
+
 * **Updated AF_XDP PMD.**
 
   * Disabled secondary process support.
@@ -121,6 +125,7 @@ New Features
 
   * Added Intel iavf support on Windows.
   * Added IPv4 and L4 (TCP/UDP/SCTP) checksum hash support in RSS flow.
+  * Added PPPoL2TPv2oUDP RSS hash based on inner IP address and TCP/UDP port.
 
 * **Updated Intel ice driver.**
 
diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
index 22ba8f0516..84cccb238d 100644
--- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
+++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
@@ -3810,6 +3810,20 @@ This section lists supported pattern items and their attributes, if any.
 
   - ``ethdev_port_id {unsigned}``: ethdev port ID
 
+- ``l2tpv2``: match L2TPV2 header.
+
+  - ``length {unsigned}``: L2TPV2 option length.
+  - ``tunnel_id {unsigned}``: L2TPV2 tunnel identifier.
+  - ``session_id {unsigned}``: L2TPV2 session identifier.
+  - ``ns {unsigned}``: L2TPV2 option ns.
+  - ``nr {unsigned}``: L2TPV2 option nr.
+
+- ``ppp``: match PPP header.
+
+  - ``addr {unsigned}``: PPP address.
+  - ``ctrl {unsigned}``: PPP control.
+  - ``proto_id {unsigned}``: PPP protocol identifier.
+
 Actions list
 ^^^^^^^^^^^^
 
@@ -5036,6 +5050,20 @@ The meter policy action list: ``green -> green, yellow -> yellow, red -> red``.
    testpmd> create port meter 0 1 13 1 yes 0xffff 0 0
    testpmd> flow create 0 priority 0 ingress group 1 pattern eth / end actions meter mtr_id 1 / end
 
+Sample PPPoL2TPv2oUDP RSS rules
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+PPPoL2TPv2oUDP RSS rules can be created by the following commands::
+
+ testpmd> flow create 0 ingress pattern eth / ipv4 / udp / l2tpv2 / ppp / ipv4
+          / end actions rss types ipv4 end queues end / end
+ testpmd> flow create 0 ingress pattern eth / ipv4 / udp / l2tpv2 / ppp / ipv6
+          / udp / end actions rss types ipv6-udp end queues end / end
+ testpmd> flow create 0 ingress pattern eth / ipv6 / udp / l2tpv2 / ppp / ipv4
+          / tcp / end actions rss types ipv4-tcp end queues end / end
+ testpmd> flow create 0 ingress pattern eth / ipv6 / udp / l2tpv2 / ppp / ipv6
+          / end actions rss types ipv6 end queues end / end
+
 BPF Functions
 --------------
 
diff --git a/lib/ethdev/rte_flow.c b/lib/ethdev/rte_flow.c
index 29f2b0e954..0bfbeb73e8 100644
--- a/lib/ethdev/rte_flow.c
+++ b/lib/ethdev/rte_flow.c
@@ -102,6 +102,8 @@ static const struct rte_flow_desc_data rte_flow_desc_item[] = {
 	MK_FLOW_ITEM(CONNTRACK, sizeof(uint32_t)),
 	MK_FLOW_ITEM(PORT_REPRESENTOR, sizeof(struct rte_flow_item_ethdev)),
 	MK_FLOW_ITEM(REPRESENTED_PORT, sizeof(struct rte_flow_item_ethdev)),
+	MK_FLOW_ITEM(L2TPV2, sizeof(struct rte_flow_item_l2tpv2)),
+	MK_FLOW_ITEM(PPP, sizeof(struct rte_flow_item_ppp)),
 };
 
 /** Generate flow_action[] entry. */
diff --git a/lib/ethdev/rte_flow.h b/lib/ethdev/rte_flow.h
index d5bfdaaaf2..2bc825b567 100644
--- a/lib/ethdev/rte_flow.h
+++ b/lib/ethdev/rte_flow.h
@@ -35,6 +35,8 @@
 #include <rte_mbuf_dyn.h>
 #include <rte_meter.h>
 #include <rte_gtp.h>
+#include <rte_l2tpv2.h>
+#include <rte_ppp.h>
 
 #ifdef __cplusplus
 extern "C" {
@@ -635,6 +637,21 @@ enum rte_flow_item_type {
 	 * @see struct rte_flow_item_ethdev
 	 */
 	RTE_FLOW_ITEM_TYPE_REPRESENTED_PORT,
+
+	/**
+	 * Matches L2TPV2 Header.
+	 *
+	 * See struct rte_flow_item_l2tpv2.
+	 */
+	RTE_FLOW_ITEM_TYPE_L2TPV2,
+
+	/**
+	 * Matches PPP Header.
+	 *
+	 * See struct rte_flow_item_ppp.
+	 */
+	RTE_FLOW_ITEM_TYPE_PPP,
+
 };
 
 /**
@@ -1891,6 +1908,55 @@ static const struct rte_flow_item_ethdev rte_flow_item_ethdev_mask = {
 };
 #endif
 
+/**
+ * @warning
+ * @b EXPERIMENTAL: this structure may change without prior notice
+ * RTE_FLOW_ITEM_TYPE_L2TPV2
+ *
+ * Matches L2TPv2 Header
+ */
+struct rte_flow_item_l2tpv2 {
+	struct rte_l2tpv2_combined_msg_hdr hdr;
+};
+
+/** Default mask for RTE_FLOW_ITEM_TYPE_L2TPV2. */
+#ifndef __cplusplus
+static const struct rte_flow_item_l2tpv2 rte_flow_item_l2tpv2_mask = {
+	/*
+	 * flags and version bit mask
+	 * 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0
+	 * T L x x S x O P x x x x V V V V
+	 */
+	.hdr = {
+		.common = {
+			.flags_version = 0xcb0f,
+		},
+	},
+};
+#endif
+
+/**
+ * @warning
+ * @b EXPERIMENTAL: this structure may change without prior notice
+ * RTE_FLOW_ITEM_TYPE_PPP
+ *
+ * Matches PPP Header
+ */
+struct rte_flow_item_ppp {
+	struct rte_ppp_hdr hdr;
+};
+
+/** Default mask for RTE_FLOW_ITEM_TYPE_PPP. */
+#ifndef __cplusplus
+static const struct rte_flow_item_ppp rte_flow_item_ppp_mask = {
+	.hdr = {
+		.addr = 0xff,
+		.ctrl = 0xff,
+		.proto_id = 0xffff,
+	}
+};
+#endif
+
 /**
  * Matching pattern item definition.
  *
diff --git a/lib/net/meson.build b/lib/net/meson.build
index a4e395e9c5..e899846578 100644
--- a/lib/net/meson.build
+++ b/lib/net/meson.build
@@ -19,6 +19,8 @@ headers = files(
         'rte_higig.h',
         'rte_ecpri.h',
         'rte_geneve.h',
+        'rte_l2tpv2.h',
+        'rte_ppp.h',
 )
 
 sources = files(
diff --git a/lib/net/rte_l2tpv2.h b/lib/net/rte_l2tpv2.h
new file mode 100644
index 0000000000..1dd1a0a1e8
--- /dev/null
+++ b/lib/net/rte_l2tpv2.h
@@ -0,0 +1,234 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright 2021 Mellanox Technologies, Ltd
+ */
+
+#ifndef _RTE_L2TPV2_H_
+#define _RTE_L2TPV2_H_
+
+/**
+ * @file
+ *
+ * L2TP header:
+ *
+ * ` 0--------------------1----------------2-------------------3`
+ *
+ * ` 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1`
+ *
+ * `+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+`
+ *
+ * `|T|L|x|x|S|x|O|P|x|x|x|x|--Ver--|-----------Length (opt)--------|`
+ *
+ * `+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+`
+ *
+ * `|-----------Tunnel ID-----------|-----------Session ID----------|`
+ *
+ * `+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+`
+ *
+ * `|-----------Ns (opt)------------|-----------Nr (opt)------------|`
+ *
+ * `+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+`
+ *
+ * `|---------Offset Size (opt)-----|---------Offset pad... (opt)`
+ *
+ * `+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+`
+ *
+ * The Type (T) bit indicates the type of message. It is set to 0 for a data
+ * message and 1 for a control message.
+ *
+ * If the Length (L) bit is 1, the Length field is present. This bit MUST be
+ * set to 1 for control messages.
+ *
+ * The x bits are reserved for future extensions. All reserved bits MUST
+ * be set to 0 on outgoing messages and ignored on incoming messages.
+ *
+ * If the Sequence (S) bit is set to 1 the Ns and Nr fields are present.
+ * The S bit MUST be set to 1 for control messages.
+ *
+ * If the Offset (O) bit is 1, the Offset Size field is present. The O
+ * bit MUST be set to 0 for control messages.
+ *
+ * If the Priority (P) bit is 1, this data message should receive
+ * preferential treatment in its local queuing and transmission.
+ * The P bit MUST be set to 0 for control messages.
+ *
+ * Ver MUST be 2, indicating the version of the L2TP data message header.
+ *
+ * The Length field indicates the total length of the message in octets.
+ *
+ * Tunnel ID indicates the identifier for the control connection.
+ *
+ * Session ID indicates the identifier for a session within a tunnel.
+ *
+ * Ns indicates the sequence number for this data or control message.
+ *
+ * Nr indicates the sequence number expected in the next control message
+ * to be received.
+ *
+ * The Offset Size field, if present, specifies the number of octets
+ * past the L2TP header at which the payload data is expected to start.
+ * Actual data within the offset padding is undefined. If the offset
+ * field is present, the L2TP header ends after the last octet of the
+ * offset padding.
+ */
+
+#include <stdint.h>
+#include <rte_byteorder.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * L2TPv2 Common Header
+ */
+RTE_STD_C11
+struct rte_l2tpv2_common_hdr {
+	union {
+		rte_be16_t flags_version;
+		/**< header flags and protocol version */
+		struct {
+#if RTE_BYTE_ORDER == RTE_LITTLE_ENDIAN
+			rte_be16_t t:1;		/**< message Type */
+			rte_be16_t l:1;		/**< length option bit*/
+			rte_be16_t res1:2;	/**< reserved */
+			rte_be16_t s:1;		/**< ns/nr option bit*/
+			rte_be16_t res2:1;	/**< reserved */
+			rte_be16_t o:1;		/**< offset option bit*/
+			rte_be16_t p:1;		/**< priority option bit*/
+			rte_be16_t res3:4;	/**< reserved */
+			rte_be16_t ver:4;	/**< protocol version */
+#elif RTE_BYTE_ORDER == RTE_BIG_ENDIAN
+			rte_be16_t ver:4;	/**< protocol version */
+			rte_be16_t res3:4;	/**< reserved */
+			rte_be16_t p:1;		/**< priority option bit*/
+			rte_be16_t o:1;		/**< offset option bit*/
+			rte_be16_t res2:1;	/**< reserved */
+			rte_be16_t s:1;		/**< ns/nr option bit*/
+			rte_be16_t res1:2;	/**< reserved */
+			rte_be16_t l:1;		/**< length option bit*/
+			rte_be16_t t:1;		/**< message Type */
+#endif
+		};
+	};
+};
+
+/**
+ * L2TPv2 message Header contains all options(length, ns, nr,
+ * offset size, offset padding).
+ */
+struct rte_l2tpv2_msg_with_all_options {
+	rte_be16_t length;		/**< length(16) */
+	rte_be16_t tunnel_id;		/**< tunnel id(16) */
+	rte_be16_t session_id;		/**< session id(16) */
+	rte_be16_t ns;			/**< Ns(16) */
+	rte_be16_t nr;			/**< Nr(16) */
+	rte_be16_t offset_size;		/**< offset size(16) */
+	uint8_t   *offset_padding;	/**< offset padding(variable length) */
+};
+
+/**
+ * L2TPv2 message Header contains all options except length(ns, nr,
+ * offset size, offset padding).
+ */
+struct rte_l2tpv2_msg_without_length {
+	rte_be16_t tunnel_id;		/**< tunnel id(16) */
+	rte_be16_t session_id;		/**< session id(16) */
+	rte_be16_t ns;			/**< Ns(16) */
+	rte_be16_t nr;			/**< Nr(16) */
+	rte_be16_t offset_size;		/**< offset size(16) */
+	uint8_t   *offset_padding;	/**< offset padding(variable length) */
+};
+
+/**
+ * L2TPv2 message Header contains all options except ns_nr(length,
+ * offset size, offset padding).
+ * Ns and Nr MUST be toghter.
+ */
+struct rte_l2tpv2_msg_without_ns_nr {
+	rte_be16_t length;		/**< length(16) */
+	rte_be16_t tunnel_id;		/**< tunnel id(16) */
+	rte_be16_t session_id;		/**< session id(16) */
+	rte_be16_t offset_size;		/**< offset size(16) */
+	uint8_t   *offset_padding;	/**< offset padding(variable length) */
+};
+
+/**
+ * L2TPv2 message Header contains all options except ns_nr(length, ns, nr).
+ * offset size and offset padding MUST be toghter.
+ */
+struct rte_l2tpv2_msg_without_offset {
+	rte_be16_t length;		/**< length(16) */
+	rte_be16_t tunnel_id;		/**< tunnel id(16) */
+	rte_be16_t session_id;		/**< session id(16) */
+	rte_be16_t ns;			/**< Ns(16) */
+	rte_be16_t nr;			/**< Nr(16) */
+};
+
+/**
+ * L2TPv2 message Header contains options offset size and offset padding.
+ */
+struct rte_l2tpv2_msg_with_offset {
+	rte_be16_t tunnel_id;		/**< tunnel id(16) */
+	rte_be16_t session_id;		/**< session id(16) */
+	rte_be16_t offset_size;		/**< offset size(16) */
+	uint8_t   *offset_padding;	/**< offset padding(variable length) */
+};
+
+/**
+ * L2TPv2 message Header contains options ns and nr.
+ */
+struct rte_l2tpv2_msg_with_ns_nr {
+	rte_be16_t tunnel_id;		/**< tunnel id(16) */
+	rte_be16_t session_id;		/**< session id(16) */
+	rte_be16_t ns;			/**< Ns(16) */
+	rte_be16_t nr;			/**< Nr(16) */
+};
+
+/**
+ * L2TPv2 message Header contains option length.
+ */
+struct rte_l2tpv2_msg_with_length {
+	rte_be16_t length;		/**< length(16) */
+	rte_be16_t tunnel_id;		/**< tunnel id(16) */
+	rte_be16_t session_id;		/**< session id(16) */
+};
+
+/**
+ * L2TPv2 message Header without all options.
+ */
+struct rte_l2tpv2_msg_without_all_options {
+	rte_be16_t tunnel_id;		/**< tunnel id(16) */
+	rte_be16_t session_id;		/**< session id(16) */
+};
+
+/**
+ * L2TPv2 Combined Message Header Format: Common Header + Options
+ */
+RTE_STD_C11
+struct rte_l2tpv2_combined_msg_hdr {
+	struct rte_l2tpv2_common_hdr common; /**< common header */
+	union {
+		struct rte_l2tpv2_msg_with_all_options type0;
+		/**< header with all options */
+		struct rte_l2tpv2_msg_without_length type1;
+		/**< header with all options except length */
+		struct rte_l2tpv2_msg_without_ns_nr type2;
+		/**< header with all options except ns/nr */
+		struct rte_l2tpv2_msg_without_offset type3;
+		/**< header with all options except offset */
+		struct rte_l2tpv2_msg_with_offset type4;
+		/**< header with offset options */
+		struct rte_l2tpv2_msg_with_ns_nr type5;
+		/**< header with ns/nr options */
+		struct rte_l2tpv2_msg_with_length type6;
+		/**< header with length option */
+		struct rte_l2tpv2_msg_without_all_options type7;
+		/**< header without all options */
+	};
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RTE_L2TPV2_H_ */
diff --git a/lib/net/rte_ppp.h b/lib/net/rte_ppp.h
new file mode 100644
index 0000000000..9ea633baa7
--- /dev/null
+++ b/lib/net/rte_ppp.h
@@ -0,0 +1,35 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright 2021 Mellanox Technologies, Ltd
+ */
+
+#ifndef _RTE_PPP_H_
+#define _RTE_PPP_H_
+
+/**
+ * @file
+ *
+ * PPP headers definition.
+ *
+ */
+
+#include <stdint.h>
+#include <rte_byteorder.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * PPP Header
+ */
+struct rte_ppp_hdr {
+	uint8_t addr; /**< ppp address(8) */
+	uint8_t ctrl; /**< ppp control(8) */
+	rte_be16_t proto_id; /**< ppp protocol id(16) */
+} __rte_packed;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RTE_PPP_H_ */
-- 
2.25.1


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

* [dpdk-dev] [PATCH v6 2/3] net/iavf: support PPPoL2TPv2oUDP RSS Hash
  2021-10-20  9:32         ` [dpdk-dev] [PATCH v6 0/3] support PPPoL2TPv2oUDP RSS Hash Jie Wang
  2021-10-20  9:32           ` [dpdk-dev] [PATCH v6 1/3] ethdev: support PPP and L2TPV2 procotol Jie Wang
@ 2021-10-20  9:32           ` Jie Wang
  2021-10-21  2:07             ` Xing, Beilei
  2021-10-20  9:32           ` [dpdk-dev] [PATCH v6 3/3] app/testpmd: support L2TPV2 and PPP protocol pattern Jie Wang
  2021-10-21  6:26           ` [dpdk-dev] [PATCH v7 0/3] support PPPoL2TPv2oUDP RSS Hash Jie Wang
  3 siblings, 1 reply; 71+ messages in thread
From: Jie Wang @ 2021-10-20  9:32 UTC (permalink / raw)
  To: dev
  Cc: orika, ferruh.yigit, thomas, andrew.rybchenko, xiaoyun.li,
	stevex.yang, jingjing.wu, beilei.xing, wenjun1.wu, qi.z.zhang,
	Jie Wang

Add support for PPP over L2TPv2 over UDP protocol RSS Hash based
on inner IP src/dst address and TCP/UDP src/dst port.

Patterns are listed below:
eth/ipv4(6)/udp/l2tpv2/ppp/ipv4(6)
eth/ipv4(6)/udp/l2tpv2/ppp/ipv4(6)/udp
eth/ipv4(6)/udp/l2tpv2/ppp/ipv4(6)/tcp

Signed-off-by: Wenjun Wu <wenjun1.wu@intel.com>
Signed-off-by: Jie Wang <jie1x.wang@intel.com>
---
 drivers/net/iavf/iavf_generic_flow.c | 131 +++++++++++++++++++++++++++
 drivers/net/iavf/iavf_generic_flow.h |  15 +++
 drivers/net/iavf/iavf_hash.c         | 108 +++++++++++++++++++++-
 3 files changed, 252 insertions(+), 2 deletions(-)

diff --git a/drivers/net/iavf/iavf_generic_flow.c b/drivers/net/iavf/iavf_generic_flow.c
index b86d99e57d..364904fa02 100644
--- a/drivers/net/iavf/iavf_generic_flow.c
+++ b/drivers/net/iavf/iavf_generic_flow.c
@@ -1611,6 +1611,137 @@ enum rte_flow_item_type iavf_pattern_eth_ipv6_gre_ipv6_udp[] = {
 	RTE_FLOW_ITEM_TYPE_END,
 };
 
+/* PPPoL2TPv2oUDP */
+enum rte_flow_item_type iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv4[] = {
+	RTE_FLOW_ITEM_TYPE_ETH,
+	RTE_FLOW_ITEM_TYPE_IPV4,
+	RTE_FLOW_ITEM_TYPE_UDP,
+	RTE_FLOW_ITEM_TYPE_L2TPV2,
+	RTE_FLOW_ITEM_TYPE_PPP,
+	RTE_FLOW_ITEM_TYPE_IPV4,
+	RTE_FLOW_ITEM_TYPE_END,
+};
+
+enum rte_flow_item_type iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv6[] = {
+	RTE_FLOW_ITEM_TYPE_ETH,
+	RTE_FLOW_ITEM_TYPE_IPV4,
+	RTE_FLOW_ITEM_TYPE_UDP,
+	RTE_FLOW_ITEM_TYPE_L2TPV2,
+	RTE_FLOW_ITEM_TYPE_PPP,
+	RTE_FLOW_ITEM_TYPE_IPV6,
+	RTE_FLOW_ITEM_TYPE_END,
+};
+
+enum rte_flow_item_type iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv4_udp[] = {
+	RTE_FLOW_ITEM_TYPE_ETH,
+	RTE_FLOW_ITEM_TYPE_IPV4,
+	RTE_FLOW_ITEM_TYPE_UDP,
+	RTE_FLOW_ITEM_TYPE_L2TPV2,
+	RTE_FLOW_ITEM_TYPE_PPP,
+	RTE_FLOW_ITEM_TYPE_IPV4,
+	RTE_FLOW_ITEM_TYPE_UDP,
+	RTE_FLOW_ITEM_TYPE_END,
+};
+
+enum rte_flow_item_type iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv4_tcp[] = {
+	RTE_FLOW_ITEM_TYPE_ETH,
+	RTE_FLOW_ITEM_TYPE_IPV4,
+	RTE_FLOW_ITEM_TYPE_UDP,
+	RTE_FLOW_ITEM_TYPE_L2TPV2,
+	RTE_FLOW_ITEM_TYPE_PPP,
+	RTE_FLOW_ITEM_TYPE_IPV4,
+	RTE_FLOW_ITEM_TYPE_TCP,
+	RTE_FLOW_ITEM_TYPE_END,
+};
+
+enum rte_flow_item_type iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv6_udp[] = {
+	RTE_FLOW_ITEM_TYPE_ETH,
+	RTE_FLOW_ITEM_TYPE_IPV4,
+	RTE_FLOW_ITEM_TYPE_UDP,
+	RTE_FLOW_ITEM_TYPE_L2TPV2,
+	RTE_FLOW_ITEM_TYPE_PPP,
+	RTE_FLOW_ITEM_TYPE_IPV6,
+	RTE_FLOW_ITEM_TYPE_UDP,
+	RTE_FLOW_ITEM_TYPE_END,
+};
+
+enum rte_flow_item_type iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv6_tcp[] = {
+	RTE_FLOW_ITEM_TYPE_ETH,
+	RTE_FLOW_ITEM_TYPE_IPV4,
+	RTE_FLOW_ITEM_TYPE_UDP,
+	RTE_FLOW_ITEM_TYPE_L2TPV2,
+	RTE_FLOW_ITEM_TYPE_PPP,
+	RTE_FLOW_ITEM_TYPE_IPV6,
+	RTE_FLOW_ITEM_TYPE_TCP,
+	RTE_FLOW_ITEM_TYPE_END,
+};
+
+enum rte_flow_item_type iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv4[] = {
+	RTE_FLOW_ITEM_TYPE_ETH,
+	RTE_FLOW_ITEM_TYPE_IPV6,
+	RTE_FLOW_ITEM_TYPE_UDP,
+	RTE_FLOW_ITEM_TYPE_L2TPV2,
+	RTE_FLOW_ITEM_TYPE_PPP,
+	RTE_FLOW_ITEM_TYPE_IPV4,
+	RTE_FLOW_ITEM_TYPE_END,
+};
+
+enum rte_flow_item_type iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv6[] = {
+	RTE_FLOW_ITEM_TYPE_ETH,
+	RTE_FLOW_ITEM_TYPE_IPV6,
+	RTE_FLOW_ITEM_TYPE_UDP,
+	RTE_FLOW_ITEM_TYPE_L2TPV2,
+	RTE_FLOW_ITEM_TYPE_PPP,
+	RTE_FLOW_ITEM_TYPE_IPV6,
+	RTE_FLOW_ITEM_TYPE_END,
+};
+
+enum rte_flow_item_type iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv4_udp[] = {
+	RTE_FLOW_ITEM_TYPE_ETH,
+	RTE_FLOW_ITEM_TYPE_IPV6,
+	RTE_FLOW_ITEM_TYPE_UDP,
+	RTE_FLOW_ITEM_TYPE_L2TPV2,
+	RTE_FLOW_ITEM_TYPE_PPP,
+	RTE_FLOW_ITEM_TYPE_IPV4,
+	RTE_FLOW_ITEM_TYPE_UDP,
+	RTE_FLOW_ITEM_TYPE_END,
+};
+
+enum rte_flow_item_type iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv4_tcp[] = {
+	RTE_FLOW_ITEM_TYPE_ETH,
+	RTE_FLOW_ITEM_TYPE_IPV6,
+	RTE_FLOW_ITEM_TYPE_UDP,
+	RTE_FLOW_ITEM_TYPE_L2TPV2,
+	RTE_FLOW_ITEM_TYPE_PPP,
+	RTE_FLOW_ITEM_TYPE_IPV4,
+	RTE_FLOW_ITEM_TYPE_TCP,
+	RTE_FLOW_ITEM_TYPE_END,
+};
+
+enum rte_flow_item_type iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv6_udp[] = {
+	RTE_FLOW_ITEM_TYPE_ETH,
+	RTE_FLOW_ITEM_TYPE_IPV6,
+	RTE_FLOW_ITEM_TYPE_UDP,
+	RTE_FLOW_ITEM_TYPE_L2TPV2,
+	RTE_FLOW_ITEM_TYPE_PPP,
+	RTE_FLOW_ITEM_TYPE_IPV6,
+	RTE_FLOW_ITEM_TYPE_UDP,
+	RTE_FLOW_ITEM_TYPE_END,
+};
+
+enum rte_flow_item_type iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv6_tcp[] = {
+	RTE_FLOW_ITEM_TYPE_ETH,
+	RTE_FLOW_ITEM_TYPE_IPV6,
+	RTE_FLOW_ITEM_TYPE_UDP,
+	RTE_FLOW_ITEM_TYPE_L2TPV2,
+	RTE_FLOW_ITEM_TYPE_PPP,
+	RTE_FLOW_ITEM_TYPE_IPV6,
+	RTE_FLOW_ITEM_TYPE_TCP,
+	RTE_FLOW_ITEM_TYPE_END,
+};
+
+
+
 typedef struct iavf_flow_engine * (*parse_engine_t)(struct iavf_adapter *ad,
 		struct rte_flow *flow,
 		struct iavf_parser_list *parser_list,
diff --git a/drivers/net/iavf/iavf_generic_flow.h b/drivers/net/iavf/iavf_generic_flow.h
index 4794d1fb80..f2b54e1944 100644
--- a/drivers/net/iavf/iavf_generic_flow.h
+++ b/drivers/net/iavf/iavf_generic_flow.h
@@ -410,6 +410,21 @@ extern enum rte_flow_item_type iavf_pattern_eth_ipv6_gre_ipv6_tcp[];
 extern enum rte_flow_item_type iavf_pattern_eth_ipv6_gre_ipv4_udp[];
 extern enum rte_flow_item_type iavf_pattern_eth_ipv6_gre_ipv6_udp[];
 
+/* PPPoL2TPv2oUDP */
+extern enum rte_flow_item_type iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv4[];
+extern enum rte_flow_item_type iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv6[];
+extern enum rte_flow_item_type iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv4_udp[];
+extern enum rte_flow_item_type iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv4_tcp[];
+extern enum rte_flow_item_type iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv6_udp[];
+extern enum rte_flow_item_type iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv6_tcp[];
+extern enum rte_flow_item_type iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv4[];
+extern enum rte_flow_item_type iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv6[];
+extern enum rte_flow_item_type iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv4_udp[];
+extern enum rte_flow_item_type iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv4_tcp[];
+extern enum rte_flow_item_type iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv6_udp[];
+extern enum rte_flow_item_type iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv6_tcp[];
+
+
 extern const struct rte_flow_ops iavf_flow_ops;
 
 /* pattern structure */
diff --git a/drivers/net/iavf/iavf_hash.c b/drivers/net/iavf/iavf_hash.c
index 1f2d3772d1..9e7286861e 100644
--- a/drivers/net/iavf/iavf_hash.c
+++ b/drivers/net/iavf/iavf_hash.c
@@ -34,6 +34,8 @@
 /* the second IP header of GTPoGRE */
 #define IAVF_PHINT_MID_IPV4			BIT_ULL(7)
 #define IAVF_PHINT_MID_IPV6			BIT_ULL(8)
+/* L2TPV2 */
+#define IAVF_PHINT_L2TPV2			BIT_ULL(9)
 
 #define IAVF_PHINT_GTPU_MSK	(IAVF_PHINT_GTPU	| \
 				 IAVF_PHINT_GTPU_EH	| \
@@ -164,6 +166,12 @@ iavf_hash_parse_pattern_action(struct iavf_adapter *ad,
 	VIRTCHNL_PROTO_HDR_ECPRI, \
 	FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_ECPRI_PC_RTC_ID), {BUFF_NOUSED} }
 
+#define proto_hdr_l2tpv2 { \
+	VIRTCHNL_PROTO_HDR_L2TPV2, 0, {BUFF_NOUSED} }
+
+#define proto_hdr_ppp { \
+	VIRTCHNL_PROTO_HDR_PPP, 0, {BUFF_NOUSED} }
+
 #define TUNNEL_LEVEL_OUTER		0
 #define TUNNEL_LEVEL_INNER		1
 
@@ -338,6 +346,52 @@ struct virtchnl_proto_hdrs ipv4_ecpri_tmplt = {
 	TUNNEL_LEVEL_OUTER, 3, {proto_hdr_ipv4, proto_hdr_udp, proto_hdr_ecpri}
 };
 
+struct virtchnl_proto_hdrs udp_l2tpv2_ppp_ipv4_tmplt = {
+	TUNNEL_LEVEL_INNER, 3,
+	{proto_hdr_l2tpv2,
+	 proto_hdr_ppp,
+	 proto_hdr_ipv4}
+};
+
+struct virtchnl_proto_hdrs udp_l2tpv2_ppp_ipv6_tmplt = {
+	TUNNEL_LEVEL_INNER, 3,
+	{proto_hdr_l2tpv2,
+	 proto_hdr_ppp,
+	 proto_hdr_ipv6}
+};
+
+struct virtchnl_proto_hdrs udp_l2tpv2_ppp_ipv4_udp_tmplt = {
+	TUNNEL_LEVEL_INNER, 4,
+	{proto_hdr_l2tpv2,
+	 proto_hdr_ppp,
+	 proto_hdr_ipv4_with_prot,
+	 proto_hdr_udp}
+};
+
+struct virtchnl_proto_hdrs udp_l2tpv2_ppp_ipv4_tcp_tmplt = {
+	TUNNEL_LEVEL_INNER, 4,
+	{proto_hdr_l2tpv2,
+	 proto_hdr_ppp,
+	 proto_hdr_ipv4_with_prot,
+	 proto_hdr_tcp}
+};
+
+struct virtchnl_proto_hdrs udp_l2tpv2_ppp_ipv6_udp_tmplt = {
+	TUNNEL_LEVEL_INNER, 4,
+	{proto_hdr_l2tpv2,
+	 proto_hdr_ppp,
+	 proto_hdr_ipv6_with_prot,
+	 proto_hdr_udp}
+};
+
+struct virtchnl_proto_hdrs udp_l2tpv2_ppp_ipv6_tcp_tmplt = {
+	TUNNEL_LEVEL_INNER, 4,
+	{proto_hdr_l2tpv2,
+	 proto_hdr_ppp,
+	 proto_hdr_ipv6_with_prot,
+	 proto_hdr_tcp}
+};
+
 /* rss type super set */
 
 /* IPv4 outer */
@@ -493,6 +547,13 @@ static struct iavf_pattern_match_item iavf_hash_pattern_list[] = {
 	{iavf_pattern_eth_ipv6_gre_ipv4_tcp,	IAVF_RSS_TYPE_INNER_IPV4_TCP, &inner_ipv4_tcp_tmplt},
 	{iavf_pattern_eth_ipv4_gre_ipv4_udp,	IAVF_RSS_TYPE_INNER_IPV4_UDP, &inner_ipv4_udp_tmplt},
 	{iavf_pattern_eth_ipv6_gre_ipv4_udp,	IAVF_RSS_TYPE_INNER_IPV4_UDP, &inner_ipv4_udp_tmplt},
+	{iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv4,	IAVF_RSS_TYPE_INNER_IPV4,	&udp_l2tpv2_ppp_ipv4_tmplt},
+	{iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv4_udp,	IAVF_RSS_TYPE_INNER_IPV4_UDP,	&udp_l2tpv2_ppp_ipv4_udp_tmplt},
+	{iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv4_tcp,	IAVF_RSS_TYPE_INNER_IPV4_TCP,	&udp_l2tpv2_ppp_ipv4_tcp_tmplt},
+	{iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv4,	IAVF_RSS_TYPE_INNER_IPV4,	&udp_l2tpv2_ppp_ipv4_tmplt},
+	{iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv4_udp,	IAVF_RSS_TYPE_INNER_IPV4_UDP,	&udp_l2tpv2_ppp_ipv4_udp_tmplt},
+	{iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv4_tcp,	IAVF_RSS_TYPE_INNER_IPV4_TCP,	&udp_l2tpv2_ppp_ipv4_tcp_tmplt},
+
 	/* IPv6 */
 	{iavf_pattern_eth_ipv6,				IAVF_RSS_TYPE_OUTER_IPV6,	&outer_ipv6_tmplt},
 	{iavf_pattern_eth_ipv6_frag_ext,		IAVF_RSS_TYPE_OUTER_IPV6_FRAG,	&outer_ipv6_frag_tmplt},
@@ -553,6 +614,13 @@ static struct iavf_pattern_match_item iavf_hash_pattern_list[] = {
 	{iavf_pattern_eth_ipv6_gre_ipv6_tcp,	IAVF_RSS_TYPE_INNER_IPV6_TCP, &inner_ipv6_tcp_tmplt},
 	{iavf_pattern_eth_ipv4_gre_ipv6_udp,	IAVF_RSS_TYPE_INNER_IPV6_UDP, &inner_ipv6_udp_tmplt},
 	{iavf_pattern_eth_ipv6_gre_ipv6_udp,	IAVF_RSS_TYPE_INNER_IPV6_UDP, &inner_ipv6_udp_tmplt},
+	{iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv6,	IAVF_RSS_TYPE_INNER_IPV6,	&udp_l2tpv2_ppp_ipv6_tmplt},
+	{iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv6_udp,	IAVF_RSS_TYPE_INNER_IPV6_UDP,	&udp_l2tpv2_ppp_ipv6_udp_tmplt},
+	{iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv6_tcp,	IAVF_RSS_TYPE_INNER_IPV6_TCP,	&udp_l2tpv2_ppp_ipv6_tcp_tmplt},
+	{iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv6,	IAVF_RSS_TYPE_INNER_IPV6,	&udp_l2tpv2_ppp_ipv6_tmplt},
+	{iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv6_udp,	IAVF_RSS_TYPE_INNER_IPV6_UDP,	&udp_l2tpv2_ppp_ipv6_udp_tmplt},
+	{iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv6_tcp,	IAVF_RSS_TYPE_INNER_IPV6_TCP,	&udp_l2tpv2_ppp_ipv6_tcp_tmplt},
+
 };
 
 static struct iavf_flow_engine iavf_hash_engine = {
@@ -687,13 +755,17 @@ iavf_hash_parse_pattern(const struct rte_flow_item pattern[], uint64_t *phint,
 
 		switch (item->type) {
 		case RTE_FLOW_ITEM_TYPE_IPV4:
-			if (!(*phint & IAVF_PHINT_GTPU_MSK) && !(*phint & IAVF_PHINT_GRE))
+			if (!(*phint & IAVF_PHINT_GTPU_MSK) &&
+			    !(*phint & IAVF_PHINT_GRE) &&
+			    !(*phint & IAVF_PHINT_L2TPV2))
 				*phint |= IAVF_PHINT_OUTER_IPV4;
 			if ((*phint & IAVF_PHINT_GRE) && !(*phint & IAVF_PHINT_GTPU_MSK))
 				*phint |= IAVF_PHINT_MID_IPV4;
 			break;
 		case RTE_FLOW_ITEM_TYPE_IPV6:
-			if (!(*phint & IAVF_PHINT_GTPU_MSK) && !(*phint & IAVF_PHINT_GRE))
+			if (!(*phint & IAVF_PHINT_GTPU_MSK) &&
+			    !(*phint & IAVF_PHINT_GRE) &&
+			    !(*phint & IAVF_PHINT_L2TPV2))
 				*phint |= IAVF_PHINT_OUTER_IPV6;
 			if ((*phint & IAVF_PHINT_GRE) && !(*phint & IAVF_PHINT_GTPU_MSK))
 				*phint |= IAVF_PHINT_MID_IPV6;
@@ -728,6 +800,10 @@ iavf_hash_parse_pattern(const struct rte_flow_item pattern[], uint64_t *phint,
 			break;
 		case RTE_FLOW_ITEM_TYPE_GRE:
 			*phint |= IAVF_PHINT_GRE;
+			break;
+		case RTE_FLOW_ITEM_TYPE_L2TPV2:
+			*phint |= IAVF_PHINT_L2TPV2;
+			break;
 		default:
 			break;
 		}
@@ -1050,12 +1126,40 @@ iavf_refine_proto_hdrs_by_pattern(struct virtchnl_proto_hdrs *proto_hdrs,
 	proto_hdrs->tunnel_level = tun_lvl;
 }
 
+static void
+iavf_refine_proto_hdrs_l2tpv2(struct virtchnl_proto_hdrs *proto_hdrs,
+			      uint64_t phint)
+{
+	struct virtchnl_proto_hdr *hdr1;
+	int i;
+
+	if (!(phint & IAVF_PHINT_L2TPV2))
+		return;
+
+	if (proto_hdrs->tunnel_level == TUNNEL_LEVEL_INNER) {
+		/* shift headers layer */
+		for (i = proto_hdrs->count - 1 + 1; i > 0; i--)
+			proto_hdrs->proto_hdr[i] = proto_hdrs->proto_hdr[i - 1];
+
+		/* adding outer ip header at layer 0 */
+		hdr1 = &proto_hdrs->proto_hdr[0];
+		hdr1->field_selector = 0;
+		proto_hdrs->count++;
+		proto_hdrs->tunnel_level = TUNNEL_LEVEL_OUTER;
+		if (phint & IAVF_PHINT_OUTER_IPV4)
+			VIRTCHNL_SET_PROTO_HDR_TYPE(hdr1, IPV4);
+		else if (phint & IAVF_PHINT_OUTER_IPV6)
+			VIRTCHNL_SET_PROTO_HDR_TYPE(hdr1, IPV6);
+	}
+}
+
 static void iavf_refine_proto_hdrs(struct virtchnl_proto_hdrs *proto_hdrs,
 				   uint64_t rss_type, uint64_t phint)
 {
 	iavf_refine_proto_hdrs_l234(proto_hdrs, rss_type);
 	iavf_refine_proto_hdrs_by_pattern(proto_hdrs, phint);
 	iavf_refine_proto_hdrs_gtpu(proto_hdrs, rss_type);
+	iavf_refine_proto_hdrs_l2tpv2(proto_hdrs, phint);
 }
 
 static uint64_t invalid_rss_comb[] = {
-- 
2.25.1


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

* [dpdk-dev] [PATCH v6 3/3] app/testpmd: support L2TPV2 and PPP protocol pattern
  2021-10-20  9:32         ` [dpdk-dev] [PATCH v6 0/3] support PPPoL2TPv2oUDP RSS Hash Jie Wang
  2021-10-20  9:32           ` [dpdk-dev] [PATCH v6 1/3] ethdev: support PPP and L2TPV2 procotol Jie Wang
  2021-10-20  9:32           ` [dpdk-dev] [PATCH v6 2/3] net/iavf: support PPPoL2TPv2oUDP RSS Hash Jie Wang
@ 2021-10-20  9:32           ` Jie Wang
  2021-10-21  6:26           ` [dpdk-dev] [PATCH v7 0/3] support PPPoL2TPv2oUDP RSS Hash Jie Wang
  3 siblings, 0 replies; 71+ messages in thread
From: Jie Wang @ 2021-10-20  9:32 UTC (permalink / raw)
  To: dev
  Cc: orika, ferruh.yigit, thomas, andrew.rybchenko, xiaoyun.li,
	stevex.yang, jingjing.wu, beilei.xing, wenjun1.wu, qi.z.zhang,
	Jie Wang

Add support for test-pmd to parse protocol pattern L2TPv2 and PPP.

Signed-off-by: Wenjun Wu <wenjun1.wu@intel.com>
Signed-off-by: Jie Wang <jie1x.wang@intel.com>
---
 app/test-pmd/cmdline_flow.c | 251 ++++++++++++++++++++++++++++++++++++
 1 file changed, 251 insertions(+)

diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
index a90822b660..c1046e3e28 100644
--- a/app/test-pmd/cmdline_flow.c
+++ b/app/test-pmd/cmdline_flow.c
@@ -310,6 +310,23 @@ enum index {
 	ITEM_PORT_REPRESENTOR_PORT_ID,
 	ITEM_REPRESENTED_PORT,
 	ITEM_REPRESENTED_PORT_ETHDEV_PORT_ID,
+	ITEM_L2TPV2,
+	ITEM_L2TPV2_COMMON,
+	ITEM_L2TPV2_COMMON_TYPE,
+	ITEM_L2TPV2_COMMON_TYPE_DATA_L,
+	ITEM_L2TPV2_COMMON_TYPE_CTRL,
+	ITEM_L2TPV2_MSG_DATA_L_LENGTH,
+	ITEM_L2TPV2_MSG_DATA_L_TUNNEL_ID,
+	ITEM_L2TPV2_MSG_DATA_L_SESSION_ID,
+	ITEM_L2TPV2_MSG_CTRL_LENGTH,
+	ITEM_L2TPV2_MSG_CTRL_TUNNEL_ID,
+	ITEM_L2TPV2_MSG_CTRL_SESSION_ID,
+	ITEM_L2TPV2_MSG_CTRL_NS,
+	ITEM_L2TPV2_MSG_CTRL_NR,
+	ITEM_PPP,
+	ITEM_PPP_ADDR,
+	ITEM_PPP_CTRL,
+	ITEM_PPP_PROTO_ID,
 
 	/* Validate/create actions. */
 	ACTIONS,
@@ -1018,6 +1035,8 @@ static const enum index next_item[] = {
 	ITEM_CONNTRACK,
 	ITEM_PORT_REPRESENTOR,
 	ITEM_REPRESENTED_PORT,
+	ITEM_L2TPV2,
+	ITEM_PPP,
 	END_SET,
 	ZERO,
 };
@@ -1398,6 +1417,31 @@ static const enum index item_represented_port[] = {
 	ZERO,
 };
 
+static const enum index item_l2tpv2[] = {
+	ITEM_L2TPV2_COMMON,
+	ITEM_NEXT,
+	ZERO,
+};
+
+static const enum index item_l2tpv2_common[] = {
+	ITEM_L2TPV2_COMMON_TYPE,
+	ZERO,
+};
+
+static const enum index item_l2tpv2_common_type[] = {
+	ITEM_L2TPV2_COMMON_TYPE_DATA_L,
+	ITEM_L2TPV2_COMMON_TYPE_CTRL,
+	ZERO,
+};
+
+static const enum index item_ppp[] = {
+	ITEM_PPP_ADDR,
+	ITEM_PPP_CTRL,
+	ITEM_PPP_PROTO_ID,
+	ITEM_NEXT,
+	ZERO,
+};
+
 static const enum index next_action[] = {
 	ACTION_END,
 	ACTION_VOID,
@@ -1781,6 +1825,9 @@ static int parse_vc_conf(struct context *, const struct token *,
 static int parse_vc_item_ecpri_type(struct context *, const struct token *,
 				    const char *, unsigned int,
 				    void *, unsigned int);
+static int parse_vc_item_l2tpv2_type(struct context *, const struct token *,
+				    const char *, unsigned int,
+				    void *, unsigned int);
 static int parse_vc_action_meter_color_type(struct context *,
 					const struct token *,
 					const char *, unsigned int, void *,
@@ -3682,6 +3729,153 @@ static const struct token token_list[] = {
 			     item_param),
 		.args = ARGS(ARGS_ENTRY(struct rte_flow_item_ethdev, port_id)),
 	},
+	[ITEM_L2TPV2] = {
+		.name = "l2tpv2",
+		.help = "match l2tpv2 header",
+		.priv = PRIV_ITEM(L2TPV2, sizeof(struct rte_flow_item_l2tpv2)),
+		.next = NEXT(item_l2tpv2),
+		.call = parse_vc,
+	},
+	[ITEM_L2TPV2_COMMON] = {
+		.name = "common",
+		.help = "l2tpv2 common header",
+		.next = NEXT(item_l2tpv2_common),
+	},
+	[ITEM_L2TPV2_COMMON_TYPE] = {
+		.name = "type",
+		.help = "type of common header",
+		.next = NEXT(item_l2tpv2_common_type),
+		.args = ARGS(ARG_ENTRY_HTON(struct rte_flow_item_l2tpv2)),
+	},
+	[ITEM_L2TPV2_COMMON_TYPE_DATA_L] = {
+		.name = "data_l",
+		.help = "Type #6: data message with length option",
+		.next = NEXT(NEXT_ENTRY(ITEM_L2TPV2_MSG_DATA_L_LENGTH,
+					ITEM_L2TPV2_MSG_DATA_L_TUNNEL_ID,
+					ITEM_L2TPV2_MSG_DATA_L_SESSION_ID,
+					ITEM_NEXT)),
+		.call = parse_vc_item_l2tpv2_type,
+	},
+	[ITEM_L2TPV2_MSG_DATA_L_LENGTH] = {
+		.name = "length",
+		.help = "message length",
+		.next = NEXT(NEXT_ENTRY(ITEM_L2TPV2_MSG_DATA_L_LENGTH,
+					ITEM_L2TPV2_COMMON, ITEM_NEXT),
+			     NEXT_ENTRY(COMMON_UNSIGNED),
+			     item_param),
+		.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2,
+					     hdr.type6.length)),
+	},
+	[ITEM_L2TPV2_MSG_DATA_L_TUNNEL_ID] = {
+		.name = "tunnel_id",
+		.help = "tunnel identifier",
+		.next = NEXT(NEXT_ENTRY(ITEM_L2TPV2_MSG_DATA_L_TUNNEL_ID,
+					ITEM_L2TPV2_COMMON, ITEM_NEXT),
+			     NEXT_ENTRY(COMMON_UNSIGNED),
+			     item_param),
+		.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2,
+					     hdr.type6.tunnel_id)),
+	},
+	[ITEM_L2TPV2_MSG_DATA_L_SESSION_ID] = {
+		.name = "session_id",
+		.help = "session identifier",
+		.next = NEXT(NEXT_ENTRY(ITEM_L2TPV2_MSG_DATA_L_SESSION_ID,
+					ITEM_L2TPV2_COMMON, ITEM_NEXT),
+			     NEXT_ENTRY(COMMON_UNSIGNED),
+			     item_param),
+		.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2,
+					     hdr.type6.session_id)),
+	},
+	[ITEM_L2TPV2_COMMON_TYPE_CTRL] = {
+		.name = "control",
+		.help = "Type #3: conrtol message contains length, ns, nr options",
+		.next = NEXT(NEXT_ENTRY(ITEM_L2TPV2_MSG_CTRL_LENGTH,
+					ITEM_L2TPV2_MSG_CTRL_TUNNEL_ID,
+					ITEM_L2TPV2_MSG_CTRL_SESSION_ID,
+					ITEM_L2TPV2_MSG_CTRL_NS,
+					ITEM_L2TPV2_MSG_CTRL_NR,
+					ITEM_NEXT)),
+		.call = parse_vc_item_l2tpv2_type,
+	},
+	[ITEM_L2TPV2_MSG_CTRL_LENGTH] = {
+		.name = "length",
+		.help = "message length",
+		.next = NEXT(NEXT_ENTRY(ITEM_L2TPV2_MSG_CTRL_LENGTH,
+					ITEM_L2TPV2_COMMON, ITEM_NEXT),
+			     NEXT_ENTRY(COMMON_UNSIGNED),
+			     item_param),
+		.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2,
+					     hdr.type3.length)),
+	},
+	[ITEM_L2TPV2_MSG_CTRL_TUNNEL_ID] = {
+		.name = "tunnel_id",
+		.help = "tunnel identifier",
+		.next = NEXT(NEXT_ENTRY(ITEM_L2TPV2_MSG_CTRL_TUNNEL_ID,
+					ITEM_L2TPV2_COMMON, ITEM_NEXT),
+			     NEXT_ENTRY(COMMON_UNSIGNED),
+			     item_param),
+		.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2,
+					     hdr.type3.tunnel_id)),
+	},
+	[ITEM_L2TPV2_MSG_CTRL_SESSION_ID] = {
+		.name = "session_id",
+		.help = "session identifier",
+		.next = NEXT(NEXT_ENTRY(ITEM_L2TPV2_MSG_CTRL_SESSION_ID,
+					ITEM_L2TPV2_COMMON, ITEM_NEXT),
+			     NEXT_ENTRY(COMMON_UNSIGNED),
+			     item_param),
+		.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2,
+					     hdr.type3.session_id)),
+	},
+	[ITEM_L2TPV2_MSG_CTRL_NS] = {
+		.name = "ns",
+		.help = "sequence number for message",
+		.next = NEXT(NEXT_ENTRY(ITEM_L2TPV2_MSG_CTRL_NS,
+					ITEM_L2TPV2_COMMON, ITEM_NEXT),
+			     NEXT_ENTRY(COMMON_UNSIGNED),
+			     item_param),
+		.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2,
+					     hdr.type3.ns)),
+	},
+	[ITEM_L2TPV2_MSG_CTRL_NR] = {
+		.name = "nr",
+		.help = "sequence number for next receive message",
+		.next = NEXT(NEXT_ENTRY(ITEM_L2TPV2_MSG_CTRL_NS,
+					ITEM_L2TPV2_COMMON, ITEM_NEXT),
+			     NEXT_ENTRY(COMMON_UNSIGNED),
+			     item_param),
+		.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2,
+					     hdr.type3.nr)),
+	},
+	[ITEM_PPP] = {
+		.name = "ppp",
+		.help = "match ppp header",
+		.priv = PRIV_ITEM(PPP, sizeof(struct rte_flow_item_ppp)),
+		.next = NEXT(item_ppp),
+		.call = parse_vc,
+	},
+	[ITEM_PPP_ADDR] = {
+		.name = "addr",
+		.help = "ppp address",
+		.next = NEXT(item_ppp, NEXT_ENTRY(COMMON_UNSIGNED),
+			     item_param),
+		.args = ARGS(ARGS_ENTRY(struct rte_flow_item_ppp, hdr.addr)),
+	},
+	[ITEM_PPP_CTRL] = {
+		.name = "ctrl",
+		.help = "ppp control",
+		.next = NEXT(item_ppp, NEXT_ENTRY(COMMON_UNSIGNED),
+			     item_param),
+		.args = ARGS(ARGS_ENTRY(struct rte_flow_item_ppp, hdr.ctrl)),
+	},
+	[ITEM_PPP_PROTO_ID] = {
+		.name = "proto_id",
+		.help = "ppp protocol id",
+		.next = NEXT(item_ppp, NEXT_ENTRY(COMMON_UNSIGNED),
+			     item_param),
+		.args = ARGS(ARGS_ENTRY(struct rte_flow_item_ppp,
+					hdr.proto_id)),
+	},
 	/* Validate/create actions. */
 	[ACTIONS] = {
 		.name = "actions",
@@ -5569,6 +5763,57 @@ parse_vc_item_ecpri_type(struct context *ctx, const struct token *token,
 	return len;
 }
 
+/** Parse L2TPV2 common header type field. */
+static int
+parse_vc_item_l2tpv2_type(struct context *ctx, const struct token *token,
+			 const char *str, unsigned int len,
+			 void *buf, unsigned int size)
+{
+	struct rte_flow_item_l2tpv2 *l2tpv2;
+	struct rte_flow_item_l2tpv2 *l2tpv2_mask;
+	struct rte_flow_item *item;
+	uint32_t data_size;
+	uint8_t msg_type = 0;
+	struct buffer *out = buf;
+	const struct arg *arg;
+
+	(void)size;
+	/* Token name must match. */
+	if (parse_default(ctx, token, str, len, NULL, 0) < 0)
+		return -1;
+	switch (ctx->curr) {
+	case ITEM_L2TPV2_COMMON_TYPE_DATA_L:
+		msg_type |= 0x4000;
+		break;
+	case ITEM_L2TPV2_COMMON_TYPE_CTRL:
+		msg_type |= 0xC800;
+		break;
+	default:
+		return -1;
+	}
+	if (!ctx->object)
+		return len;
+	arg = pop_args(ctx);
+	if (!arg)
+		return -1;
+	l2tpv2 = (struct rte_flow_item_l2tpv2 *)out->args.vc.data;
+	l2tpv2->hdr.common.flags_version |= msg_type;
+	data_size = ctx->objdata / 3; /* spec, last, mask */
+	l2tpv2_mask = (struct rte_flow_item_l2tpv2 *)(out->args.vc.data +
+						    (data_size * 2));
+	l2tpv2_mask->hdr.common.flags_version = 0xFFFF;
+	if (arg->hton) {
+		l2tpv2->hdr.common.flags_version =
+			rte_cpu_to_be_16(l2tpv2->hdr.common.flags_version);
+		l2tpv2_mask->hdr.common.flags_version =
+		    rte_cpu_to_be_16(l2tpv2_mask->hdr.common.flags_version);
+	}
+	item = &out->args.vc.pattern[out->args.vc.pattern_n - 1];
+	item->spec = l2tpv2;
+	item->mask = l2tpv2_mask;
+	return len;
+}
+
 /** Parse meter color action type. */
 static int
 parse_vc_action_meter_color_type(struct context *ctx, const struct token *token,
@@ -8461,6 +8706,12 @@ flow_item_default_mask(const struct rte_flow_item *item)
 	case RTE_FLOW_ITEM_TYPE_REPRESENTED_PORT:
 		mask = &rte_flow_item_ethdev_mask;
 		break;
+	case RTE_FLOW_ITEM_TYPE_L2TPV2:
+		mask = &rte_flow_item_l2tpv2_mask;
+		break;
+	case RTE_FLOW_ITEM_TYPE_PPP:
+		mask = &rte_flow_item_ppp_mask;
+		break;
 	default:
 		break;
 	}
-- 
2.25.1


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

* Re: [dpdk-dev] [PATCH v6 1/3] ethdev: support PPP and L2TPV2 procotol
  2021-10-20  9:32           ` [dpdk-dev] [PATCH v6 1/3] ethdev: support PPP and L2TPV2 procotol Jie Wang
@ 2021-10-20  9:53             ` Andrew Rybchenko
  0 siblings, 0 replies; 71+ messages in thread
From: Andrew Rybchenko @ 2021-10-20  9:53 UTC (permalink / raw)
  To: Jie Wang, dev
  Cc: orika, ferruh.yigit, thomas, xiaoyun.li, stevex.yang,
	jingjing.wu, beilei.xing, wenjun1.wu, qi.z.zhang

On 10/20/21 12:32 PM, Jie Wang wrote:
> Added flow pattern items and header formats of L2TPv2 and PPP.
> 
> Signed-off-by: Wenjun Wu <wenjun1.wu@intel.com>
> Signed-off-by: Jie Wang <jie1x.wang@intel.com>

Newly added items must be added to
doc/guides/nics/features/default.ini in correct order.

When the item is supported, ini file of the corresponding
driver must be updated.

> ---
>  doc/api/doxy-api-index.md                   |   2 +
>  doc/guides/prog_guide/rte_flow.rst          |  25 +++
>  doc/guides/rel_notes/release_21_11.rst      |   5 +
>  doc/guides/testpmd_app_ug/testpmd_funcs.rst |  28 +++
>  lib/ethdev/rte_flow.c                       |   2 +
>  lib/ethdev/rte_flow.h                       |  66 ++++++
>  lib/net/meson.build                         |   2 +
>  lib/net/rte_l2tpv2.h                        | 234 ++++++++++++++++++++
>  lib/net/rte_ppp.h                           |  35 +++
>  9 files changed, 399 insertions(+)
>  create mode 100644 lib/net/rte_l2tpv2.h
>  create mode 100644 lib/net/rte_ppp.h
> 
> diff --git a/doc/api/doxy-api-index.md b/doc/api/doxy-api-index.md
> index 1992107a03..43b64d06c1 100644
> --- a/doc/api/doxy-api-index.md
> +++ b/doc/api/doxy-api-index.md
> @@ -121,6 +121,8 @@ The public API headers are grouped by topics:
>    [VXLAN]              (@ref rte_vxlan.h),
>    [Geneve]             (@ref rte_geneve.h),
>    [eCPRI]              (@ref rte_ecpri.h)
> +  [L2TPV2]             (@ref rte_l2tpv2.h)

Is it a canonical spelling? Shouldn't it be L2TPv2?
If you change, it should be changed everywhere in comments.

> +  [PPP]                (@ref rte_ppp.h)
>  
>  - **QoS**:
>    [metering]           (@ref rte_meter.h),
> diff --git a/doc/guides/prog_guide/rte_flow.rst b/doc/guides/prog_guide/rte_flow.rst
> index fa05fe0845..6277c641ef 100644
> --- a/doc/guides/prog_guide/rte_flow.rst
> +++ b/doc/guides/prog_guide/rte_flow.rst
> @@ -1548,6 +1548,31 @@ This item is meant to use the same structure as `Item: PORT_REPRESENTOR`_.
>  
>  See also `Action: REPRESENTED_PORT`_.
>  
> +Item: ``L2TPV2``
> +^^^^^^^^^^^^^^^^^^^
> +
> +Matches a L2TPv2 header.
> +
> +- ``flags_version``: flags(12b), version(4b).
> +- ``length``: total length of the message.
> +- ``tunnel_id``: identifier for the control connection.
> +- ``session_id``: identifier for a session within a tunnel.
> +- ``ns``: sequence number for this date or control message.
> +- ``nr``: sequence number expected in the next control message to be received.
> +- ``offset_size``: offset of payload data.
> +- ``offset_padding``: offset padding, variable length.
> +- Default ``mask`` matches flags_version only.
> +
> +Item: ``PPP``
> +^^^^^^^^^^^^^^^^^^^
> +
> +Matches a PPP header.
> +
> +- ``addr``: ppp address.
> +- ``ctrl``: ppp control.
> +- ``proto_id``: ppp protocol identifier.

ppp -> PPP everywhere above

> +- Default ``mask`` matches addr, ctrl, proto_id.
> +
>  Actions
>  ~~~~~~~
>  
> diff --git a/doc/guides/rel_notes/release_21_11.rst b/doc/guides/rel_notes/release_21_11.rst
> index c5f76081e5..9fea43ece7 100644
> --- a/doc/guides/rel_notes/release_21_11.rst
> +++ b/doc/guides/rel_notes/release_21_11.rst
> @@ -98,6 +98,10 @@ New Features
>  
>    Added an ethdev API which can help users get device configuration.
>  
> +* **Added L2TPV2 and PPP protocol support in rte_flow.**
> +
> +  Added flow pattern items and header formats of L2TPv2 and PPP protocol.
> +
>  * **Updated AF_XDP PMD.**
>  
>    * Disabled secondary process support.
> @@ -121,6 +125,7 @@ New Features
>  
>    * Added Intel iavf support on Windows.
>    * Added IPv4 and L4 (TCP/UDP/SCTP) checksum hash support in RSS flow.
> +  * Added PPPoL2TPv2oUDP RSS hash based on inner IP address and TCP/UDP port.

I think it belongs to the next patch which adds driver support.

>  
>  * **Updated Intel ice driver.**
>  
> diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
> index 22ba8f0516..84cccb238d 100644
> --- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
> +++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
> @@ -3810,6 +3810,20 @@ This section lists supported pattern items and their attributes, if any.
>  
>    - ``ethdev_port_id {unsigned}``: ethdev port ID
>  
> +- ``l2tpv2``: match L2TPV2 header.
> +
> +  - ``length {unsigned}``: L2TPV2 option length.
> +  - ``tunnel_id {unsigned}``: L2TPV2 tunnel identifier.
> +  - ``session_id {unsigned}``: L2TPV2 session identifier.
> +  - ``ns {unsigned}``: L2TPV2 option ns.
> +  - ``nr {unsigned}``: L2TPV2 option nr.
> +
> +- ``ppp``: match PPP header.
> +
> +  - ``addr {unsigned}``: PPP address.
> +  - ``ctrl {unsigned}``: PPP control.
> +  - ``proto_id {unsigned}``: PPP protocol identifier.
> +
>  Actions list
>  ^^^^^^^^^^^^
>  
> @@ -5036,6 +5050,20 @@ The meter policy action list: ``green -> green, yellow -> yellow, red -> red``.
>     testpmd> create port meter 0 1 13 1 yes 0xffff 0 0
>     testpmd> flow create 0 priority 0 ingress group 1 pattern eth / end actions meter mtr_id 1 / end
>  
> +Sample PPPoL2TPv2oUDP RSS rules
> +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> +
> +PPPoL2TPv2oUDP RSS rules can be created by the following commands::
> +
> + testpmd> flow create 0 ingress pattern eth / ipv4 / udp / l2tpv2 / ppp / ipv4
> +          / end actions rss types ipv4 end queues end / end
> + testpmd> flow create 0 ingress pattern eth / ipv4 / udp / l2tpv2 / ppp / ipv6
> +          / udp / end actions rss types ipv6-udp end queues end / end
> + testpmd> flow create 0 ingress pattern eth / ipv6 / udp / l2tpv2 / ppp / ipv4
> +          / tcp / end actions rss types ipv4-tcp end queues end / end
> + testpmd> flow create 0 ingress pattern eth / ipv6 / udp / l2tpv2 / ppp / ipv6
> +          / end actions rss types ipv6 end queues end / end
> +
>  BPF Functions
>  --------------
>  
> diff --git a/lib/ethdev/rte_flow.c b/lib/ethdev/rte_flow.c
> index 29f2b0e954..0bfbeb73e8 100644
> --- a/lib/ethdev/rte_flow.c
> +++ b/lib/ethdev/rte_flow.c
> @@ -102,6 +102,8 @@ static const struct rte_flow_desc_data rte_flow_desc_item[] = {
>  	MK_FLOW_ITEM(CONNTRACK, sizeof(uint32_t)),
>  	MK_FLOW_ITEM(PORT_REPRESENTOR, sizeof(struct rte_flow_item_ethdev)),
>  	MK_FLOW_ITEM(REPRESENTED_PORT, sizeof(struct rte_flow_item_ethdev)),
> +	MK_FLOW_ITEM(L2TPV2, sizeof(struct rte_flow_item_l2tpv2)),
> +	MK_FLOW_ITEM(PPP, sizeof(struct rte_flow_item_ppp)),
>  };
>  
>  /** Generate flow_action[] entry. */
> diff --git a/lib/ethdev/rte_flow.h b/lib/ethdev/rte_flow.h
> index d5bfdaaaf2..2bc825b567 100644
> --- a/lib/ethdev/rte_flow.h
> +++ b/lib/ethdev/rte_flow.h
> @@ -35,6 +35,8 @@
>  #include <rte_mbuf_dyn.h>
>  #include <rte_meter.h>
>  #include <rte_gtp.h>
> +#include <rte_l2tpv2.h>
> +#include <rte_ppp.h>
>  
>  #ifdef __cplusplus
>  extern "C" {
> @@ -635,6 +637,21 @@ enum rte_flow_item_type {
>  	 * @see struct rte_flow_item_ethdev
>  	 */
>  	RTE_FLOW_ITEM_TYPE_REPRESENTED_PORT,
> +
> +	/**
> +	 * Matches L2TPV2 Header.
> +	 *
> +	 * See struct rte_flow_item_l2tpv2.
> +	 */
> +	RTE_FLOW_ITEM_TYPE_L2TPV2,
> +
> +	/**
> +	 * Matches PPP Header.
> +	 *
> +	 * See struct rte_flow_item_ppp.
> +	 */
> +	RTE_FLOW_ITEM_TYPE_PPP,
> +
>  };
>  
>  /**
> @@ -1891,6 +1908,55 @@ static const struct rte_flow_item_ethdev rte_flow_item_ethdev_mask = {
>  };
>  #endif
>  
> +/**
> + * @warning
> + * @b EXPERIMENTAL: this structure may change without prior notice
> + * RTE_FLOW_ITEM_TYPE_L2TPV2
> + *
> + * Matches L2TPv2 Header
> + */
> +struct rte_flow_item_l2tpv2 {
> +	struct rte_l2tpv2_combined_msg_hdr hdr;
> +};
> +
> +/** Default mask for RTE_FLOW_ITEM_TYPE_L2TPV2. */
> +#ifndef __cplusplus
> +static const struct rte_flow_item_l2tpv2 rte_flow_item_l2tpv2_mask = {
> +	/*
> +	 * flags and version bit mask
> +	 * 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0
> +	 * T L x x S x O P x x x x V V V V
> +	 */
> +	.hdr = {
> +		.common = {
> +			.flags_version = 0xcb0f,

RTE_BE16 ?

> +		},
> +	},
> +};
> +#endif
> +
> +/**
> + * @warning
> + * @b EXPERIMENTAL: this structure may change without prior notice
> + * RTE_FLOW_ITEM_TYPE_PPP
> + *
> + * Matches PPP Header
> + */
> +struct rte_flow_item_ppp {
> +	struct rte_ppp_hdr hdr;
> +};
> +
> +/** Default mask for RTE_FLOW_ITEM_TYPE_PPP. */
> +#ifndef __cplusplus
> +static const struct rte_flow_item_ppp rte_flow_item_ppp_mask = {
> +	.hdr = {
> +		.addr = 0xff,
> +		.ctrl = 0xff,
> +		.proto_id = 0xffff,

RTE_BE16 ?

> +	}
> +};
> +#endif
> +
>  /**
>   * Matching pattern item definition.
>   *
> diff --git a/lib/net/meson.build b/lib/net/meson.build
> index a4e395e9c5..e899846578 100644
> --- a/lib/net/meson.build
> +++ b/lib/net/meson.build
> @@ -19,6 +19,8 @@ headers = files(
>          'rte_higig.h',
>          'rte_ecpri.h',
>          'rte_geneve.h',
> +        'rte_l2tpv2.h',
> +        'rte_ppp.h',
>  )
>  
>  sources = files(
> diff --git a/lib/net/rte_l2tpv2.h b/lib/net/rte_l2tpv2.h
> new file mode 100644
> index 0000000000..1dd1a0a1e8
> --- /dev/null
> +++ b/lib/net/rte_l2tpv2.h
> @@ -0,0 +1,234 @@
> +/* SPDX-License-Identifier: BSD-3-Clause
> + * Copyright 2021 Mellanox Technologies, Ltd
> + */
> +
> +#ifndef _RTE_L2TPV2_H_
> +#define _RTE_L2TPV2_H_
> +
> +/**
> + * @file
> + *
> + * L2TP header:
> + *
> + * ` 0--------------------1----------------2-------------------3`
> + *
> + * ` 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1`
> + *
> + * `+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+`
> + *
> + * `|T|L|x|x|S|x|O|P|x|x|x|x|--Ver--|-----------Length (opt)--------|`
> + *
> + * `+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+`
> + *
> + * `|-----------Tunnel ID-----------|-----------Session ID----------|`
> + *
> + * `+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+`
> + *
> + * `|-----------Ns (opt)------------|-----------Nr (opt)------------|`
> + *
> + * `+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+`
> + *
> + * `|---------Offset Size (opt)-----|---------Offset pad... (opt)`
> + *
> + * `+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+`
> + *
> + * The Type (T) bit indicates the type of message. It is set to 0 for a data
> + * message and 1 for a control message.
> + *
> + * If the Length (L) bit is 1, the Length field is present. This bit MUST be
> + * set to 1 for control messages.
> + *
> + * The x bits are reserved for future extensions. All reserved bits MUST
> + * be set to 0 on outgoing messages and ignored on incoming messages.
> + *
> + * If the Sequence (S) bit is set to 1 the Ns and Nr fields are present.
> + * The S bit MUST be set to 1 for control messages.
> + *
> + * If the Offset (O) bit is 1, the Offset Size field is present. The O
> + * bit MUST be set to 0 for control messages.
> + *
> + * If the Priority (P) bit is 1, this data message should receive
> + * preferential treatment in its local queuing and transmission.
> + * The P bit MUST be set to 0 for control messages.
> + *
> + * Ver MUST be 2, indicating the version of the L2TP data message header.
> + *
> + * The Length field indicates the total length of the message in octets.
> + *
> + * Tunnel ID indicates the identifier for the control connection.
> + *
> + * Session ID indicates the identifier for a session within a tunnel.
> + *
> + * Ns indicates the sequence number for this data or control message.
> + *
> + * Nr indicates the sequence number expected in the next control message
> + * to be received.
> + *
> + * The Offset Size field, if present, specifies the number of octets
> + * past the L2TP header at which the payload data is expected to start.
> + * Actual data within the offset padding is undefined. If the offset
> + * field is present, the L2TP header ends after the last octet of the
> + * offset padding.
> + */
> +
> +#include <stdint.h>
> +#include <rte_byteorder.h>
> +
> +#ifdef __cplusplus
> +extern "C" {
> +#endif
> +
> +/**
> + * L2TPv2 Common Header
> + */
> +RTE_STD_C11
> +struct rte_l2tpv2_common_hdr {
> +	union {
> +		rte_be16_t flags_version;
> +		/**< header flags and protocol version */
> +		struct {
> +#if RTE_BYTE_ORDER == RTE_LITTLE_ENDIAN
> +			rte_be16_t t:1;		/**< message Type */
> +			rte_be16_t l:1;		/**< length option bit*/

missing space before */ here and in a number of cases below

> +			rte_be16_t res1:2;	/**< reserved */
> +			rte_be16_t s:1;		/**< ns/nr option bit*/
> +			rte_be16_t res2:1;	/**< reserved */
> +			rte_be16_t o:1;		/**< offset option bit*/
> +			rte_be16_t p:1;		/**< priority option bit*/
> +			rte_be16_t res3:4;	/**< reserved */
> +			rte_be16_t ver:4;	/**< protocol version */
> +#elif RTE_BYTE_ORDER == RTE_BIG_ENDIAN
> +			rte_be16_t ver:4;	/**< protocol version */
> +			rte_be16_t res3:4;	/**< reserved */
> +			rte_be16_t p:1;		/**< priority option bit*/
> +			rte_be16_t o:1;		/**< offset option bit*/
> +			rte_be16_t res2:1;	/**< reserved */
> +			rte_be16_t s:1;		/**< ns/nr option bit*/
> +			rte_be16_t res1:2;	/**< reserved */
> +			rte_be16_t l:1;		/**< length option bit*/
> +			rte_be16_t t:1;		/**< message Type */
> +#endif
> +		};
> +	};
> +};
> +
> +/**
> + * L2TPv2 message Header contains all options(length, ns, nr,
> + * offset size, offset padding).
> + */
> +struct rte_l2tpv2_msg_with_all_options {
> +	rte_be16_t length;		/**< length(16) */
> +	rte_be16_t tunnel_id;		/**< tunnel id(16) */
> +	rte_be16_t session_id;		/**< session id(16) */

id -> ID in comments as word-cases.txt says

> +	rte_be16_t ns;			/**< Ns(16) */
> +	rte_be16_t nr;			/**< Nr(16) */
> +	rte_be16_t offset_size;		/**< offset size(16) */
> +	uint8_t   *offset_padding;	/**< offset padding(variable length) */
> +};
> +
> +/**
> + * L2TPv2 message Header contains all options except length(ns, nr,
> + * offset size, offset padding).
> + */
> +struct rte_l2tpv2_msg_without_length {
> +	rte_be16_t tunnel_id;		/**< tunnel id(16) */
> +	rte_be16_t session_id;		/**< session id(16) */

id -> ID in comments as word-cases.txt says

> +	rte_be16_t ns;			/**< Ns(16) */
> +	rte_be16_t nr;			/**< Nr(16) */
> +	rte_be16_t offset_size;		/**< offset size(16) */
> +	uint8_t   *offset_padding;	/**< offset padding(variable length) */
> +};
> +
> +/**
> + * L2TPv2 message Header contains all options except ns_nr(length,
> + * offset size, offset padding).
> + * Ns and Nr MUST be toghter.
> + */
> +struct rte_l2tpv2_msg_without_ns_nr {
> +	rte_be16_t length;		/**< length(16) */
> +	rte_be16_t tunnel_id;		/**< tunnel id(16) */
> +	rte_be16_t session_id;		/**< session id(16) */

id -> ID in comments as word-cases.txt says

> +	rte_be16_t offset_size;		/**< offset size(16) */
> +	uint8_t   *offset_padding;	/**< offset padding(variable length) */
> +};
> +
> +/**
> + * L2TPv2 message Header contains all options except ns_nr(length, ns, nr).
> + * offset size and offset padding MUST be toghter.
> + */
> +struct rte_l2tpv2_msg_without_offset {
> +	rte_be16_t length;		/**< length(16) */
> +	rte_be16_t tunnel_id;		/**< tunnel id(16) */
> +	rte_be16_t session_id;		/**< session id(16) */

id -> ID in comments as word-cases.txt says

> +	rte_be16_t ns;			/**< Ns(16) */
> +	rte_be16_t nr;			/**< Nr(16) */
> +};
> +
> +/**
> + * L2TPv2 message Header contains options offset size and offset padding.
> + */
> +struct rte_l2tpv2_msg_with_offset {
> +	rte_be16_t tunnel_id;		/**< tunnel id(16) */
> +	rte_be16_t session_id;		/**< session id(16) */
> +	rte_be16_t offset_size;		/**< offset size(16) */
> +	uint8_t   *offset_padding;	/**< offset padding(variable length) */
> +};
> +
> +/**
> + * L2TPv2 message Header contains options ns and nr.
> + */
> +struct rte_l2tpv2_msg_with_ns_nr {
> +	rte_be16_t tunnel_id;		/**< tunnel id(16) */
> +	rte_be16_t session_id;		/**< session id(16) */

id -> ID in comments as word-cases.txt says

> +	rte_be16_t ns;			/**< Ns(16) */
> +	rte_be16_t nr;			/**< Nr(16) */
> +};
> +
> +/**
> + * L2TPv2 message Header contains option length.
> + */
> +struct rte_l2tpv2_msg_with_length {
> +	rte_be16_t length;		/**< length(16) */
> +	rte_be16_t tunnel_id;		/**< tunnel id(16) */
> +	rte_be16_t session_id;		/**< session id(16) */

id -> ID in comments as word-cases.txt says

> +};
> +
> +/**
> + * L2TPv2 message Header without all options.
> + */
> +struct rte_l2tpv2_msg_without_all_options {
> +	rte_be16_t tunnel_id;		/**< tunnel id(16) */
> +	rte_be16_t session_id;		/**< session id(16) */

id -> ID in comments as word-cases.txt says

> +};
> +
> +/**
> + * L2TPv2 Combined Message Header Format: Common Header + Options
> + */
> +RTE_STD_C11
> +struct rte_l2tpv2_combined_msg_hdr {
> +	struct rte_l2tpv2_common_hdr common; /**< common header */
> +	union {
> +		struct rte_l2tpv2_msg_with_all_options type0;
> +		/**< header with all options */

Please, no documentation after documented code.
Put it before as coding style suggests.
Same everywhere below

> +		struct rte_l2tpv2_msg_without_length type1;
> +		/**< header with all options except length */
> +		struct rte_l2tpv2_msg_without_ns_nr type2;
> +		/**< header with all options except ns/nr */
> +		struct rte_l2tpv2_msg_without_offset type3;
> +		/**< header with all options except offset */
> +		struct rte_l2tpv2_msg_with_offset type4;
> +		/**< header with offset options */
> +		struct rte_l2tpv2_msg_with_ns_nr type5;
> +		/**< header with ns/nr options */
> +		struct rte_l2tpv2_msg_with_length type6;
> +		/**< header with length option */
> +		struct rte_l2tpv2_msg_without_all_options type7;
> +		/**< header without all options */
> +	};
> +};
> +
> +#ifdef __cplusplus
> +}
> +#endif
> +
> +#endif /* _RTE_L2TPV2_H_ */
> diff --git a/lib/net/rte_ppp.h b/lib/net/rte_ppp.h
> new file mode 100644
> index 0000000000..9ea633baa7
> --- /dev/null
> +++ b/lib/net/rte_ppp.h
> @@ -0,0 +1,35 @@
> +/* SPDX-License-Identifier: BSD-3-Clause
> + * Copyright 2021 Mellanox Technologies, Ltd
> + */
> +
> +#ifndef _RTE_PPP_H_
> +#define _RTE_PPP_H_
> +
> +/**
> + * @file
> + *
> + * PPP headers definition.
> + *

Is the empty line required here?

> + */
> +
> +#include <stdint.h>
> +#include <rte_byteorder.h>
> +
> +#ifdef __cplusplus
> +extern "C" {
> +#endif
> +
> +/**
> + * PPP Header
> + */
> +struct rte_ppp_hdr {
> +	uint8_t addr; /**< ppp address(8) */
> +	uint8_t ctrl; /**< ppp control(8) */
> +	rte_be16_t proto_id; /**< ppp protocol id(16) */

ppp -> PPP everywhere above
id -> ID

> +} __rte_packed;
> +
> +#ifdef __cplusplus
> +}
> +#endif
> +
> +#endif /* _RTE_PPP_H_ */
> 


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

* Re: [dpdk-dev] [PATCH v6 2/3] net/iavf: support PPPoL2TPv2oUDP RSS Hash
  2021-10-20  9:32           ` [dpdk-dev] [PATCH v6 2/3] net/iavf: support PPPoL2TPv2oUDP RSS Hash Jie Wang
@ 2021-10-21  2:07             ` Xing, Beilei
  0 siblings, 0 replies; 71+ messages in thread
From: Xing, Beilei @ 2021-10-21  2:07 UTC (permalink / raw)
  To: Wang, Jie1X, dev
  Cc: orika, Yigit, Ferruh, thomas, andrew.rybchenko, Li, Xiaoyun,
	Yang, SteveX, Wu,  Jingjing, Wu, Wenjun1, Zhang, Qi Z



> -----Original Message-----
> From: Wang, Jie1X <jie1x.wang@intel.com>
> Sent: Wednesday, October 20, 2021 5:32 PM
> To: dev@dpdk.org
> Cc: orika@nvidia.com; Yigit, Ferruh <ferruh.yigit@intel.com>;
> thomas@monjalon.net; andrew.rybchenko@oktetlabs.ru; Li, Xiaoyun
> <xiaoyun.li@intel.com>; Yang, SteveX <stevex.yang@intel.com>; Wu, Jingjing
> <jingjing.wu@intel.com>; Xing, Beilei <beilei.xing@intel.com>; Wu, Wenjun1
> <wenjun1.wu@intel.com>; Zhang, Qi Z <qi.z.zhang@intel.com>; Wang, Jie1X
> <jie1x.wang@intel.com>
> Subject: [PATCH v6 2/3] net/iavf: support PPPoL2TPv2oUDP RSS Hash
> 
> Add support for PPP over L2TPv2 over UDP protocol RSS Hash based on inner
> IP src/dst address and TCP/UDP src/dst port.
> 
> Patterns are listed below:
> eth/ipv4(6)/udp/l2tpv2/ppp/ipv4(6)
> eth/ipv4(6)/udp/l2tpv2/ppp/ipv4(6)/udp
> eth/ipv4(6)/udp/l2tpv2/ppp/ipv4(6)/tcp
> 
> Signed-off-by: Wenjun Wu <wenjun1.wu@intel.com>
> Signed-off-by: Jie Wang <jie1x.wang@intel.com>

Acked-by: Beilei Xing <beilei.xing@intel.com>

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

* [dpdk-dev] [PATCH v7 0/3] support PPPoL2TPv2oUDP RSS Hash
  2021-10-20  9:32         ` [dpdk-dev] [PATCH v6 0/3] support PPPoL2TPv2oUDP RSS Hash Jie Wang
                             ` (2 preceding siblings ...)
  2021-10-20  9:32           ` [dpdk-dev] [PATCH v6 3/3] app/testpmd: support L2TPV2 and PPP protocol pattern Jie Wang
@ 2021-10-21  6:26           ` Jie Wang
  2021-10-21  6:26             ` [dpdk-dev] [PATCH v7 1/3] ethdev: support L2TPv2 and PPP procotol Jie Wang
                               ` (3 more replies)
  3 siblings, 4 replies; 71+ messages in thread
From: Jie Wang @ 2021-10-21  6:26 UTC (permalink / raw)
  To: dev
  Cc: orika, ferruh.yigit, thomas, andrew.rybchenko, xiaoyun.li,
	stevex.yang, jingjing.wu, beilei.xing, wenjun1.wu, qi.z.zhang,
	Jie Wang

Support IAVF PPPoL2TPv2oUDP RSS Hash. Required to distribute packets
based on inner IP src+dest address and TCP/UDP src+dest port.

---
V7:
 * update ini file.
 * modify irregular spelling.
v6:
 * update release notes.
 * update lib/net/meson.build.
 * update testpmd_funcs.rst.
 * update doxygen comments in header files.
 * update doc/api/doxy-api-index.md.
v5: update release notes.
v4:
 * update commit log.
 * redefine PPP protocol header.
 * delete l2tpv2_encap.
v3:
 * add testpmd match PPP and L2TPv2 protocol header fields value.
 * add the code of l2tpv2_encap.
 * update the title of ethdev patch and adjust the position of
   the added code.
v2:
 * update the rte_flow.rst and release notes.
 * update l2tpv2 header format.

Jie Wang (3):
  ethdev: support L2TPv2 and PPP procotol
  net/iavf: support PPPoL2TPv2oUDP RSS Hash
  app/testpmd: support L2TPv2 and PPP protocol pattern

 app/test-pmd/cmdline_flow.c                 | 251 ++++++++++++++++++++
 doc/api/doxy-api-index.md                   |   2 +
 doc/guides/nics/features/default.ini        |   2 +
 doc/guides/nics/features/iavf.ini           |   2 +
 doc/guides/prog_guide/rte_flow.rst          |  25 ++
 doc/guides/rel_notes/release_21_11.rst      |   5 +
 doc/guides/testpmd_app_ug/testpmd_funcs.rst |  28 +++
 drivers/net/iavf/iavf_generic_flow.c        | 131 ++++++++++
 drivers/net/iavf/iavf_generic_flow.h        |  15 ++
 drivers/net/iavf/iavf_hash.c                | 108 ++++++++-
 lib/ethdev/rte_flow.c                       |   2 +
 lib/ethdev/rte_flow.h                       |  65 +++++
 lib/net/meson.build                         |   2 +
 lib/net/rte_l2tpv2.h                        | 234 ++++++++++++++++++
 lib/net/rte_ppp.h                           |  34 +++
 15 files changed, 904 insertions(+), 2 deletions(-)
 create mode 100644 lib/net/rte_l2tpv2.h
 create mode 100644 lib/net/rte_ppp.h

-- 
2.25.1


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

* [dpdk-dev] [PATCH v7 1/3] ethdev: support L2TPv2 and PPP procotol
  2021-10-21  6:26           ` [dpdk-dev] [PATCH v7 0/3] support PPPoL2TPv2oUDP RSS Hash Jie Wang
@ 2021-10-21  6:26             ` Jie Wang
  2021-10-21  7:50               ` Ori Kam
  2021-10-21  9:29               ` Ferruh Yigit
  2021-10-21  6:26             ` [dpdk-dev] [PATCH v7 2/3] net/iavf: support PPPoL2TPv2oUDP RSS Hash Jie Wang
                               ` (2 subsequent siblings)
  3 siblings, 2 replies; 71+ messages in thread
From: Jie Wang @ 2021-10-21  6:26 UTC (permalink / raw)
  To: dev
  Cc: orika, ferruh.yigit, thomas, andrew.rybchenko, xiaoyun.li,
	stevex.yang, jingjing.wu, beilei.xing, wenjun1.wu, qi.z.zhang,
	Jie Wang

Added flow pattern items and header formats of L2TPv2 and PPP.

Signed-off-by: Wenjun Wu <wenjun1.wu@intel.com>
Signed-off-by: Jie Wang <jie1x.wang@intel.com>
---
 doc/api/doxy-api-index.md              |   2 +
 doc/guides/nics/features/default.ini   |   2 +
 doc/guides/nics/features/iavf.ini      |   2 +
 doc/guides/prog_guide/rte_flow.rst     |  25 +++
 doc/guides/rel_notes/release_21_11.rst |   4 +
 lib/ethdev/rte_flow.c                  |   2 +
 lib/ethdev/rte_flow.h                  |  65 +++++++
 lib/net/meson.build                    |   2 +
 lib/net/rte_l2tpv2.h                   | 234 +++++++++++++++++++++++++
 lib/net/rte_ppp.h                      |  34 ++++
 10 files changed, 372 insertions(+)
 create mode 100644 lib/net/rte_l2tpv2.h
 create mode 100644 lib/net/rte_ppp.h

diff --git a/doc/api/doxy-api-index.md b/doc/api/doxy-api-index.md
index 1992107a03..42db196afe 100644
--- a/doc/api/doxy-api-index.md
+++ b/doc/api/doxy-api-index.md
@@ -121,6 +121,8 @@ The public API headers are grouped by topics:
   [VXLAN]              (@ref rte_vxlan.h),
   [Geneve]             (@ref rte_geneve.h),
   [eCPRI]              (@ref rte_ecpri.h)
+  [L2TPv2]             (@ref rte_l2tpv2.h)
+  [PPP]                (@ref rte_ppp.h)
 
 - **QoS**:
   [metering]           (@ref rte_meter.h),
diff --git a/doc/guides/nics/features/default.ini b/doc/guides/nics/features/default.ini
index 09914b1ad3..8e6a28c419 100644
--- a/doc/guides/nics/features/default.ini
+++ b/doc/guides/nics/features/default.ini
@@ -110,6 +110,7 @@ ipv4                 =
 ipv6                 =
 ipv6_ext             =
 ipv6_frag_ext        =
+l2tpv2               =
 l2tpv3oip            =
 mark                 =
 meta                 =
@@ -121,6 +122,7 @@ pfcp                 =
 phy_port             =
 port_id              =
 port_representor     =
+ppp                  =
 pppoed               =
 pppoes               =
 pppoe_proto_id       =
diff --git a/doc/guides/nics/features/iavf.ini b/doc/guides/nics/features/iavf.ini
index d00ca934c3..a916275b88 100644
--- a/doc/guides/nics/features/iavf.ini
+++ b/doc/guides/nics/features/iavf.ini
@@ -50,8 +50,10 @@ icmp6                = Y
 ipv4                 = Y
 ipv6                 = Y
 ipv6_frag_ext        = Y
+l2tpv2               = Y
 l2tpv3oip            = Y
 pfcp                 = Y
+ppp                  = Y
 sctp                 = Y
 tcp                  = Y
 udp                  = Y
diff --git a/doc/guides/prog_guide/rte_flow.rst b/doc/guides/prog_guide/rte_flow.rst
index aeba374182..a2169517c3 100644
--- a/doc/guides/prog_guide/rte_flow.rst
+++ b/doc/guides/prog_guide/rte_flow.rst
@@ -1573,6 +1573,31 @@ rte_flow_flex_item_create() routine.
   as padded with trailing zeroes up to full configured length, both for
   value and mask.
 
+Item: ``L2TPV2``
+^^^^^^^^^^^^^^^^^^^
+
+Matches a L2TPv2 header.
+
+- ``flags_version``: flags(12b), version(4b).
+- ``length``: total length of the message.
+- ``tunnel_id``: identifier for the control connection.
+- ``session_id``: identifier for a session within a tunnel.
+- ``ns``: sequence number for this date or control message.
+- ``nr``: sequence number expected in the next control message to be received.
+- ``offset_size``: offset of payload data.
+- ``offset_padding``: offset padding, variable length.
+- Default ``mask`` matches flags_version only.
+
+Item: ``PPP``
+^^^^^^^^^^^^^^^^^^^
+
+Matches a PPP header.
+
+- ``addr``: PPP address.
+- ``ctrl``: PPP control.
+- ``proto_id``: PPP protocol identifier.
+- Default ``mask`` matches addr, ctrl, proto_id.
+
 Actions
 ~~~~~~~
 
diff --git a/doc/guides/rel_notes/release_21_11.rst b/doc/guides/rel_notes/release_21_11.rst
index 041383ee2a..283770131c 100644
--- a/doc/guides/rel_notes/release_21_11.rst
+++ b/doc/guides/rel_notes/release_21_11.rst
@@ -105,6 +105,10 @@ New Features
 
   Added an ethdev API which can help users get device configuration.
 
+* **Added L2TPv2 and PPP protocol support in rte_flow.**
+
+  Added flow pattern items and header formats of L2TPv2 and PPP protocol.
+
 * **Updated AF_XDP PMD.**
 
   * Disabled secondary process support.
diff --git a/lib/ethdev/rte_flow.c b/lib/ethdev/rte_flow.c
index bcf0513b3c..d268784532 100644
--- a/lib/ethdev/rte_flow.c
+++ b/lib/ethdev/rte_flow.c
@@ -156,6 +156,8 @@ static const struct rte_flow_desc_data rte_flow_desc_item[] = {
 	MK_FLOW_ITEM(REPRESENTED_PORT, sizeof(struct rte_flow_item_ethdev)),
 	MK_FLOW_ITEM_FN(FLEX, sizeof(struct rte_flow_item_flex),
 			rte_flow_item_flex_conv),
+	MK_FLOW_ITEM(L2TPV2, sizeof(struct rte_flow_item_l2tpv2)),
+	MK_FLOW_ITEM(PPP, sizeof(struct rte_flow_item_ppp)),
 };
 
 /** Generate flow_action[] entry. */
diff --git a/lib/ethdev/rte_flow.h b/lib/ethdev/rte_flow.h
index 64ed7f2618..300e99e16b 100644
--- a/lib/ethdev/rte_flow.h
+++ b/lib/ethdev/rte_flow.h
@@ -35,6 +35,8 @@
 #include <rte_mbuf_dyn.h>
 #include <rte_meter.h>
 #include <rte_gtp.h>
+#include <rte_l2tpv2.h>
+#include <rte_ppp.h>
 
 #ifdef __cplusplus
 extern "C" {
@@ -644,6 +646,20 @@ enum rte_flow_item_type {
 	 * @see struct rte_flow_item_flex.
 	 */
 	RTE_FLOW_ITEM_TYPE_FLEX,
+
+	/**
+	 * Matches L2TPv2 Header.
+	 *
+	 * See struct rte_flow_item_l2tpv2.
+	 */
+	RTE_FLOW_ITEM_TYPE_L2TPV2,
+
+	/**
+	 * Matches PPP Header.
+	 *
+	 * See struct rte_flow_item_ppp.
+	 */
+	RTE_FLOW_ITEM_TYPE_PPP,
 };
 
 /**
@@ -1900,6 +1916,55 @@ static const struct rte_flow_item_ethdev rte_flow_item_ethdev_mask = {
 };
 #endif
 
+/**
+ * @warning
+ * @b EXPERIMENTAL: this structure may change without prior notice
+ * RTE_FLOW_ITEM_TYPE_L2TPV2
+ *
+ * Matches L2TPv2 Header
+ */
+struct rte_flow_item_l2tpv2 {
+	struct rte_l2tpv2_combined_msg_hdr hdr;
+};
+
+/** Default mask for RTE_FLOW_ITEM_TYPE_L2TPV2. */
+#ifndef __cplusplus
+static const struct rte_flow_item_l2tpv2 rte_flow_item_l2tpv2_mask = {
+	/*
+	 * flags and version bit mask
+	 * 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0
+	 * T L x x S x O P x x x x V V V V
+	 */
+	.hdr = {
+		.common = {
+			.flags_version = RTE_BE16(0xcb0f),
+		},
+	},
+};
+#endif
+
+/**
+ * @warning
+ * @b EXPERIMENTAL: this structure may change without prior notice
+ * RTE_FLOW_ITEM_TYPE_PPP
+ *
+ * Matches PPP Header
+ */
+struct rte_flow_item_ppp {
+	struct rte_ppp_hdr hdr;
+};
+
+/** Default mask for RTE_FLOW_ITEM_TYPE_PPP. */
+#ifndef __cplusplus
+static const struct rte_flow_item_ppp rte_flow_item_ppp_mask = {
+	.hdr = {
+		.addr = 0xff,
+		.ctrl = 0xff,
+		.proto_id = RTE_BE16(0xffff),
+	}
+};
+#endif
+
 /**
  * Matching pattern item definition.
  *
diff --git a/lib/net/meson.build b/lib/net/meson.build
index a4e395e9c5..e899846578 100644
--- a/lib/net/meson.build
+++ b/lib/net/meson.build
@@ -19,6 +19,8 @@ headers = files(
         'rte_higig.h',
         'rte_ecpri.h',
         'rte_geneve.h',
+        'rte_l2tpv2.h',
+        'rte_ppp.h',
 )
 
 sources = files(
diff --git a/lib/net/rte_l2tpv2.h b/lib/net/rte_l2tpv2.h
new file mode 100644
index 0000000000..18ea759ff4
--- /dev/null
+++ b/lib/net/rte_l2tpv2.h
@@ -0,0 +1,234 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright 2021 Mellanox Technologies, Ltd
+ */
+
+#ifndef _RTE_L2TPV2_H_
+#define _RTE_L2TPV2_H_
+
+/**
+ * @file
+ *
+ * L2TP header:
+ *
+ * `-0--------------------1----------------2-------------------3`
+ *
+ * `-0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1`
+ *
+ * `+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+`
+ *
+ * `|T|L|x|x|S|x|O|P|x|x|x|x|--Ver--|-----------Length (opt)--------|`
+ *
+ * `+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+`
+ *
+ * `|-----------Tunnel ID-----------|-----------Session ID----------|`
+ *
+ * `+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+`
+ *
+ * `|-----------Ns (opt)------------|-----------Nr (opt)------------|`
+ *
+ * `+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+`
+ *
+ * `|---------Offset Size (opt)-----|---------Offset pad... (opt)`
+ *
+ * `+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+`
+ *
+ * The Type (T) bit indicates the type of message. It is set to 0 for a data
+ * message and 1 for a control message.
+ *
+ * If the Length (L) bit is 1, the Length field is present. This bit MUST be
+ * set to 1 for control messages.
+ *
+ * The x bits are reserved for future extensions. All reserved bits MUST
+ * be set to 0 on outgoing messages and ignored on incoming messages.
+ *
+ * If the Sequence (S) bit is set to 1 the Ns and Nr fields are present.
+ * The S bit MUST be set to 1 for control messages.
+ *
+ * If the Offset (O) bit is 1, the Offset Size field is present. The O
+ * bit MUST be set to 0 for control messages.
+ *
+ * If the Priority (P) bit is 1, this data message should receive
+ * preferential treatment in its local queuing and transmission.
+ * The P bit MUST be set to 0 for control messages.
+ *
+ * Ver MUST be 2, indicating the version of the L2TP data message header.
+ *
+ * The Length field indicates the total length of the message in octets.
+ *
+ * Tunnel ID indicates the identifier for the control connection.
+ *
+ * Session ID indicates the identifier for a session within a tunnel.
+ *
+ * Ns indicates the sequence number for this data or control message.
+ *
+ * Nr indicates the sequence number expected in the next control message
+ * to be received.
+ *
+ * The Offset Size field, if present, specifies the number of octets
+ * past the L2TP header at which the payload data is expected to start.
+ * Actual data within the offset padding is undefined. If the offset
+ * field is present, the L2TP header ends after the last octet of the
+ * offset padding.
+ */
+
+#include <stdint.h>
+#include <rte_byteorder.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * L2TPv2 Common Header
+ */
+RTE_STD_C11
+struct rte_l2tpv2_common_hdr {
+	union {
+		/** header flags and protocol version */
+		rte_be16_t flags_version;
+		struct {
+#if RTE_BYTE_ORDER == RTE_LITTLE_ENDIAN
+			rte_be16_t t:1;		/**< message Type */
+			rte_be16_t l:1;		/**< length option bit */
+			rte_be16_t res1:2;	/**< reserved */
+			rte_be16_t s:1;		/**< ns/nr option bit */
+			rte_be16_t res2:1;	/**< reserved */
+			rte_be16_t o:1;		/**< offset option bit */
+			rte_be16_t p:1;		/**< priority option bit */
+			rte_be16_t res3:4;	/**< reserved */
+			rte_be16_t ver:4;	/**< protocol version */
+#elif RTE_BYTE_ORDER == RTE_BIG_ENDIAN
+			rte_be16_t ver:4;	/**< protocol version */
+			rte_be16_t res3:4;	/**< reserved */
+			rte_be16_t p:1;		/**< priority option bit */
+			rte_be16_t o:1;		/**< offset option bit */
+			rte_be16_t res2:1;	/**< reserved */
+			rte_be16_t s:1;		/**< ns/nr option bit */
+			rte_be16_t res1:2;	/**< reserved */
+			rte_be16_t l:1;		/**< length option bit */
+			rte_be16_t t:1;		/**< message Type */
+#endif
+		};
+	};
+};
+
+/**
+ * L2TPv2 message Header contains all options(length, ns, nr,
+ * offset size, offset padding).
+ */
+struct rte_l2tpv2_msg_with_all_options {
+	rte_be16_t length;		/**< length(16) */
+	rte_be16_t tunnel_id;		/**< tunnel ID(16) */
+	rte_be16_t session_id;		/**< session ID(16) */
+	rte_be16_t ns;			/**< Ns(16) */
+	rte_be16_t nr;			/**< Nr(16) */
+	rte_be16_t offset_size;		/**< offset size(16) */
+	uint8_t   *offset_padding;	/**< offset padding(variable length) */
+};
+
+/**
+ * L2TPv2 message Header contains all options except length(ns, nr,
+ * offset size, offset padding).
+ */
+struct rte_l2tpv2_msg_without_length {
+	rte_be16_t tunnel_id;		/**< tunnel ID(16) */
+	rte_be16_t session_id;		/**< session ID(16) */
+	rte_be16_t ns;			/**< Ns(16) */
+	rte_be16_t nr;			/**< Nr(16) */
+	rte_be16_t offset_size;		/**< offset size(16) */
+	uint8_t   *offset_padding;	/**< offset padding(variable length) */
+};
+
+/**
+ * L2TPv2 message Header contains all options except ns_nr(length,
+ * offset size, offset padding).
+ * Ns and Nr MUST be toghter.
+ */
+struct rte_l2tpv2_msg_without_ns_nr {
+	rte_be16_t length;		/**< length(16) */
+	rte_be16_t tunnel_id;		/**< tunnel ID(16) */
+	rte_be16_t session_id;		/**< session ID(16) */
+	rte_be16_t offset_size;		/**< offset size(16) */
+	uint8_t   *offset_padding;	/**< offset padding(variable length) */
+};
+
+/**
+ * L2TPv2 message Header contains all options except ns_nr(length, ns, nr).
+ * offset size and offset padding MUST be toghter.
+ */
+struct rte_l2tpv2_msg_without_offset {
+	rte_be16_t length;		/**< length(16) */
+	rte_be16_t tunnel_id;		/**< tunnel ID(16) */
+	rte_be16_t session_id;		/**< session ID(16) */
+	rte_be16_t ns;			/**< Ns(16) */
+	rte_be16_t nr;			/**< Nr(16) */
+};
+
+/**
+ * L2TPv2 message Header contains options offset size and offset padding.
+ */
+struct rte_l2tpv2_msg_with_offset {
+	rte_be16_t tunnel_id;		/**< tunnel ID(16) */
+	rte_be16_t session_id;		/**< session ID(16) */
+	rte_be16_t offset_size;		/**< offset size(16) */
+	uint8_t   *offset_padding;	/**< offset padding(variable length) */
+};
+
+/**
+ * L2TPv2 message Header contains options ns and nr.
+ */
+struct rte_l2tpv2_msg_with_ns_nr {
+	rte_be16_t tunnel_id;		/**< tunnel ID(16) */
+	rte_be16_t session_id;		/**< session ID(16) */
+	rte_be16_t ns;			/**< Ns(16) */
+	rte_be16_t nr;			/**< Nr(16) */
+};
+
+/**
+ * L2TPv2 message Header contains option length.
+ */
+struct rte_l2tpv2_msg_with_length {
+	rte_be16_t length;		/**< length(16) */
+	rte_be16_t tunnel_id;		/**< tunnel ID(16) */
+	rte_be16_t session_id;		/**< session ID(16) */
+};
+
+/**
+ * L2TPv2 message Header without all options.
+ */
+struct rte_l2tpv2_msg_without_all_options {
+	rte_be16_t tunnel_id;		/**< tunnel ID(16) */
+	rte_be16_t session_id;		/**< session ID(16) */
+};
+
+/**
+ * L2TPv2 Combined Message Header Format: Common Header + Options
+ */
+RTE_STD_C11
+struct rte_l2tpv2_combined_msg_hdr {
+	struct rte_l2tpv2_common_hdr common; /**< common header */
+	union {
+		/** header with all options */
+		struct rte_l2tpv2_msg_with_all_options type0;
+		/** header with all options except length */
+		struct rte_l2tpv2_msg_without_length type1;
+		/** header with all options except ns/nr */
+		struct rte_l2tpv2_msg_without_ns_nr type2;
+		/** header with all options except offset */
+		struct rte_l2tpv2_msg_without_offset type3;
+		/** header with offset options */
+		struct rte_l2tpv2_msg_with_offset type4;
+		/** header with ns/nr options */
+		struct rte_l2tpv2_msg_with_ns_nr type5;
+		/** header with length option */
+		struct rte_l2tpv2_msg_with_length type6;
+		/** header without all options */
+		struct rte_l2tpv2_msg_without_all_options type7;
+	};
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RTE_L2TPV2_H_ */
diff --git a/lib/net/rte_ppp.h b/lib/net/rte_ppp.h
new file mode 100644
index 0000000000..2a53cd969f
--- /dev/null
+++ b/lib/net/rte_ppp.h
@@ -0,0 +1,34 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright 2021 Mellanox Technologies, Ltd
+ */
+
+#ifndef _RTE_PPP_H_
+#define _RTE_PPP_H_
+
+/**
+ * @file
+ *
+ * PPP headers definition.
+ */
+
+#include <stdint.h>
+#include <rte_byteorder.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * PPP Header
+ */
+struct rte_ppp_hdr {
+	uint8_t addr; /**< PPP address(8) */
+	uint8_t ctrl; /**< PPP control(8) */
+	rte_be16_t proto_id; /**< PPP protocol identifier(16) */
+} __rte_packed;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RTE_PPP_H_ */
-- 
2.25.1


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

* [dpdk-dev] [PATCH v7 2/3] net/iavf: support PPPoL2TPv2oUDP RSS Hash
  2021-10-21  6:26           ` [dpdk-dev] [PATCH v7 0/3] support PPPoL2TPv2oUDP RSS Hash Jie Wang
  2021-10-21  6:26             ` [dpdk-dev] [PATCH v7 1/3] ethdev: support L2TPv2 and PPP procotol Jie Wang
@ 2021-10-21  6:26             ` Jie Wang
  2021-10-21  6:26             ` [dpdk-dev] [PATCH v7 3/3] app/testpmd: support L2TPv2 and PPP protocol pattern Jie Wang
  2021-10-21 10:05             ` [dpdk-dev] [PATCH v8 0/3] support PPPoL2TPv2oUDP RSS Hash Jie Wang
  3 siblings, 0 replies; 71+ messages in thread
From: Jie Wang @ 2021-10-21  6:26 UTC (permalink / raw)
  To: dev
  Cc: orika, ferruh.yigit, thomas, andrew.rybchenko, xiaoyun.li,
	stevex.yang, jingjing.wu, beilei.xing, wenjun1.wu, qi.z.zhang,
	Jie Wang

Add support for PPP over L2TPv2 over UDP protocol RSS Hash based
on inner IP src/dst address and TCP/UDP src/dst port.

Patterns are listed below:
eth/ipv4(6)/udp/l2tpv2/ppp/ipv4(6)
eth/ipv4(6)/udp/l2tpv2/ppp/ipv4(6)/udp
eth/ipv4(6)/udp/l2tpv2/ppp/ipv4(6)/tcp

Acked-by: Beilei Xing <beilei.xing@intel.com>
Signed-off-by: Wenjun Wu <wenjun1.wu@intel.com>
Signed-off-by: Jie Wang <jie1x.wang@intel.com>
---
 doc/guides/rel_notes/release_21_11.rst |   1 +
 drivers/net/iavf/iavf_generic_flow.c   | 131 +++++++++++++++++++++++++
 drivers/net/iavf/iavf_generic_flow.h   |  15 +++
 drivers/net/iavf/iavf_hash.c           | 108 +++++++++++++++++++-
 4 files changed, 253 insertions(+), 2 deletions(-)

diff --git a/doc/guides/rel_notes/release_21_11.rst b/doc/guides/rel_notes/release_21_11.rst
index 283770131c..bd0eacc0c5 100644
--- a/doc/guides/rel_notes/release_21_11.rst
+++ b/doc/guides/rel_notes/release_21_11.rst
@@ -132,6 +132,7 @@ New Features
 
   * Added Intel iavf support on Windows.
   * Added IPv4 and L4 (TCP/UDP/SCTP) checksum hash support in RSS flow.
+  * Added PPPoL2TPv2oUDP RSS hash based on inner IP address and TCP/UDP port.
 
 * **Updated Intel ice driver.**
 
diff --git a/drivers/net/iavf/iavf_generic_flow.c b/drivers/net/iavf/iavf_generic_flow.c
index b86d99e57d..364904fa02 100644
--- a/drivers/net/iavf/iavf_generic_flow.c
+++ b/drivers/net/iavf/iavf_generic_flow.c
@@ -1611,6 +1611,137 @@ enum rte_flow_item_type iavf_pattern_eth_ipv6_gre_ipv6_udp[] = {
 	RTE_FLOW_ITEM_TYPE_END,
 };
 
+/* PPPoL2TPv2oUDP */
+enum rte_flow_item_type iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv4[] = {
+	RTE_FLOW_ITEM_TYPE_ETH,
+	RTE_FLOW_ITEM_TYPE_IPV4,
+	RTE_FLOW_ITEM_TYPE_UDP,
+	RTE_FLOW_ITEM_TYPE_L2TPV2,
+	RTE_FLOW_ITEM_TYPE_PPP,
+	RTE_FLOW_ITEM_TYPE_IPV4,
+	RTE_FLOW_ITEM_TYPE_END,
+};
+
+enum rte_flow_item_type iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv6[] = {
+	RTE_FLOW_ITEM_TYPE_ETH,
+	RTE_FLOW_ITEM_TYPE_IPV4,
+	RTE_FLOW_ITEM_TYPE_UDP,
+	RTE_FLOW_ITEM_TYPE_L2TPV2,
+	RTE_FLOW_ITEM_TYPE_PPP,
+	RTE_FLOW_ITEM_TYPE_IPV6,
+	RTE_FLOW_ITEM_TYPE_END,
+};
+
+enum rte_flow_item_type iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv4_udp[] = {
+	RTE_FLOW_ITEM_TYPE_ETH,
+	RTE_FLOW_ITEM_TYPE_IPV4,
+	RTE_FLOW_ITEM_TYPE_UDP,
+	RTE_FLOW_ITEM_TYPE_L2TPV2,
+	RTE_FLOW_ITEM_TYPE_PPP,
+	RTE_FLOW_ITEM_TYPE_IPV4,
+	RTE_FLOW_ITEM_TYPE_UDP,
+	RTE_FLOW_ITEM_TYPE_END,
+};
+
+enum rte_flow_item_type iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv4_tcp[] = {
+	RTE_FLOW_ITEM_TYPE_ETH,
+	RTE_FLOW_ITEM_TYPE_IPV4,
+	RTE_FLOW_ITEM_TYPE_UDP,
+	RTE_FLOW_ITEM_TYPE_L2TPV2,
+	RTE_FLOW_ITEM_TYPE_PPP,
+	RTE_FLOW_ITEM_TYPE_IPV4,
+	RTE_FLOW_ITEM_TYPE_TCP,
+	RTE_FLOW_ITEM_TYPE_END,
+};
+
+enum rte_flow_item_type iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv6_udp[] = {
+	RTE_FLOW_ITEM_TYPE_ETH,
+	RTE_FLOW_ITEM_TYPE_IPV4,
+	RTE_FLOW_ITEM_TYPE_UDP,
+	RTE_FLOW_ITEM_TYPE_L2TPV2,
+	RTE_FLOW_ITEM_TYPE_PPP,
+	RTE_FLOW_ITEM_TYPE_IPV6,
+	RTE_FLOW_ITEM_TYPE_UDP,
+	RTE_FLOW_ITEM_TYPE_END,
+};
+
+enum rte_flow_item_type iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv6_tcp[] = {
+	RTE_FLOW_ITEM_TYPE_ETH,
+	RTE_FLOW_ITEM_TYPE_IPV4,
+	RTE_FLOW_ITEM_TYPE_UDP,
+	RTE_FLOW_ITEM_TYPE_L2TPV2,
+	RTE_FLOW_ITEM_TYPE_PPP,
+	RTE_FLOW_ITEM_TYPE_IPV6,
+	RTE_FLOW_ITEM_TYPE_TCP,
+	RTE_FLOW_ITEM_TYPE_END,
+};
+
+enum rte_flow_item_type iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv4[] = {
+	RTE_FLOW_ITEM_TYPE_ETH,
+	RTE_FLOW_ITEM_TYPE_IPV6,
+	RTE_FLOW_ITEM_TYPE_UDP,
+	RTE_FLOW_ITEM_TYPE_L2TPV2,
+	RTE_FLOW_ITEM_TYPE_PPP,
+	RTE_FLOW_ITEM_TYPE_IPV4,
+	RTE_FLOW_ITEM_TYPE_END,
+};
+
+enum rte_flow_item_type iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv6[] = {
+	RTE_FLOW_ITEM_TYPE_ETH,
+	RTE_FLOW_ITEM_TYPE_IPV6,
+	RTE_FLOW_ITEM_TYPE_UDP,
+	RTE_FLOW_ITEM_TYPE_L2TPV2,
+	RTE_FLOW_ITEM_TYPE_PPP,
+	RTE_FLOW_ITEM_TYPE_IPV6,
+	RTE_FLOW_ITEM_TYPE_END,
+};
+
+enum rte_flow_item_type iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv4_udp[] = {
+	RTE_FLOW_ITEM_TYPE_ETH,
+	RTE_FLOW_ITEM_TYPE_IPV6,
+	RTE_FLOW_ITEM_TYPE_UDP,
+	RTE_FLOW_ITEM_TYPE_L2TPV2,
+	RTE_FLOW_ITEM_TYPE_PPP,
+	RTE_FLOW_ITEM_TYPE_IPV4,
+	RTE_FLOW_ITEM_TYPE_UDP,
+	RTE_FLOW_ITEM_TYPE_END,
+};
+
+enum rte_flow_item_type iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv4_tcp[] = {
+	RTE_FLOW_ITEM_TYPE_ETH,
+	RTE_FLOW_ITEM_TYPE_IPV6,
+	RTE_FLOW_ITEM_TYPE_UDP,
+	RTE_FLOW_ITEM_TYPE_L2TPV2,
+	RTE_FLOW_ITEM_TYPE_PPP,
+	RTE_FLOW_ITEM_TYPE_IPV4,
+	RTE_FLOW_ITEM_TYPE_TCP,
+	RTE_FLOW_ITEM_TYPE_END,
+};
+
+enum rte_flow_item_type iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv6_udp[] = {
+	RTE_FLOW_ITEM_TYPE_ETH,
+	RTE_FLOW_ITEM_TYPE_IPV6,
+	RTE_FLOW_ITEM_TYPE_UDP,
+	RTE_FLOW_ITEM_TYPE_L2TPV2,
+	RTE_FLOW_ITEM_TYPE_PPP,
+	RTE_FLOW_ITEM_TYPE_IPV6,
+	RTE_FLOW_ITEM_TYPE_UDP,
+	RTE_FLOW_ITEM_TYPE_END,
+};
+
+enum rte_flow_item_type iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv6_tcp[] = {
+	RTE_FLOW_ITEM_TYPE_ETH,
+	RTE_FLOW_ITEM_TYPE_IPV6,
+	RTE_FLOW_ITEM_TYPE_UDP,
+	RTE_FLOW_ITEM_TYPE_L2TPV2,
+	RTE_FLOW_ITEM_TYPE_PPP,
+	RTE_FLOW_ITEM_TYPE_IPV6,
+	RTE_FLOW_ITEM_TYPE_TCP,
+	RTE_FLOW_ITEM_TYPE_END,
+};
+
+
+
 typedef struct iavf_flow_engine * (*parse_engine_t)(struct iavf_adapter *ad,
 		struct rte_flow *flow,
 		struct iavf_parser_list *parser_list,
diff --git a/drivers/net/iavf/iavf_generic_flow.h b/drivers/net/iavf/iavf_generic_flow.h
index 4794d1fb80..f2b54e1944 100644
--- a/drivers/net/iavf/iavf_generic_flow.h
+++ b/drivers/net/iavf/iavf_generic_flow.h
@@ -410,6 +410,21 @@ extern enum rte_flow_item_type iavf_pattern_eth_ipv6_gre_ipv6_tcp[];
 extern enum rte_flow_item_type iavf_pattern_eth_ipv6_gre_ipv4_udp[];
 extern enum rte_flow_item_type iavf_pattern_eth_ipv6_gre_ipv6_udp[];
 
+/* PPPoL2TPv2oUDP */
+extern enum rte_flow_item_type iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv4[];
+extern enum rte_flow_item_type iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv6[];
+extern enum rte_flow_item_type iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv4_udp[];
+extern enum rte_flow_item_type iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv4_tcp[];
+extern enum rte_flow_item_type iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv6_udp[];
+extern enum rte_flow_item_type iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv6_tcp[];
+extern enum rte_flow_item_type iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv4[];
+extern enum rte_flow_item_type iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv6[];
+extern enum rte_flow_item_type iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv4_udp[];
+extern enum rte_flow_item_type iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv4_tcp[];
+extern enum rte_flow_item_type iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv6_udp[];
+extern enum rte_flow_item_type iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv6_tcp[];
+
+
 extern const struct rte_flow_ops iavf_flow_ops;
 
 /* pattern structure */
diff --git a/drivers/net/iavf/iavf_hash.c b/drivers/net/iavf/iavf_hash.c
index 1f2d3772d1..01724cd569 100644
--- a/drivers/net/iavf/iavf_hash.c
+++ b/drivers/net/iavf/iavf_hash.c
@@ -34,6 +34,8 @@
 /* the second IP header of GTPoGRE */
 #define IAVF_PHINT_MID_IPV4			BIT_ULL(7)
 #define IAVF_PHINT_MID_IPV6			BIT_ULL(8)
+/* L2TPv2 */
+#define IAVF_PHINT_L2TPV2			BIT_ULL(9)
 
 #define IAVF_PHINT_GTPU_MSK	(IAVF_PHINT_GTPU	| \
 				 IAVF_PHINT_GTPU_EH	| \
@@ -164,6 +166,12 @@ iavf_hash_parse_pattern_action(struct iavf_adapter *ad,
 	VIRTCHNL_PROTO_HDR_ECPRI, \
 	FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_ECPRI_PC_RTC_ID), {BUFF_NOUSED} }
 
+#define proto_hdr_l2tpv2 { \
+	VIRTCHNL_PROTO_HDR_L2TPV2, 0, {BUFF_NOUSED} }
+
+#define proto_hdr_ppp { \
+	VIRTCHNL_PROTO_HDR_PPP, 0, {BUFF_NOUSED} }
+
 #define TUNNEL_LEVEL_OUTER		0
 #define TUNNEL_LEVEL_INNER		1
 
@@ -338,6 +346,52 @@ struct virtchnl_proto_hdrs ipv4_ecpri_tmplt = {
 	TUNNEL_LEVEL_OUTER, 3, {proto_hdr_ipv4, proto_hdr_udp, proto_hdr_ecpri}
 };
 
+struct virtchnl_proto_hdrs udp_l2tpv2_ppp_ipv4_tmplt = {
+	TUNNEL_LEVEL_INNER, 3,
+	{proto_hdr_l2tpv2,
+	 proto_hdr_ppp,
+	 proto_hdr_ipv4}
+};
+
+struct virtchnl_proto_hdrs udp_l2tpv2_ppp_ipv6_tmplt = {
+	TUNNEL_LEVEL_INNER, 3,
+	{proto_hdr_l2tpv2,
+	 proto_hdr_ppp,
+	 proto_hdr_ipv6}
+};
+
+struct virtchnl_proto_hdrs udp_l2tpv2_ppp_ipv4_udp_tmplt = {
+	TUNNEL_LEVEL_INNER, 4,
+	{proto_hdr_l2tpv2,
+	 proto_hdr_ppp,
+	 proto_hdr_ipv4_with_prot,
+	 proto_hdr_udp}
+};
+
+struct virtchnl_proto_hdrs udp_l2tpv2_ppp_ipv4_tcp_tmplt = {
+	TUNNEL_LEVEL_INNER, 4,
+	{proto_hdr_l2tpv2,
+	 proto_hdr_ppp,
+	 proto_hdr_ipv4_with_prot,
+	 proto_hdr_tcp}
+};
+
+struct virtchnl_proto_hdrs udp_l2tpv2_ppp_ipv6_udp_tmplt = {
+	TUNNEL_LEVEL_INNER, 4,
+	{proto_hdr_l2tpv2,
+	 proto_hdr_ppp,
+	 proto_hdr_ipv6_with_prot,
+	 proto_hdr_udp}
+};
+
+struct virtchnl_proto_hdrs udp_l2tpv2_ppp_ipv6_tcp_tmplt = {
+	TUNNEL_LEVEL_INNER, 4,
+	{proto_hdr_l2tpv2,
+	 proto_hdr_ppp,
+	 proto_hdr_ipv6_with_prot,
+	 proto_hdr_tcp}
+};
+
 /* rss type super set */
 
 /* IPv4 outer */
@@ -493,6 +547,13 @@ static struct iavf_pattern_match_item iavf_hash_pattern_list[] = {
 	{iavf_pattern_eth_ipv6_gre_ipv4_tcp,	IAVF_RSS_TYPE_INNER_IPV4_TCP, &inner_ipv4_tcp_tmplt},
 	{iavf_pattern_eth_ipv4_gre_ipv4_udp,	IAVF_RSS_TYPE_INNER_IPV4_UDP, &inner_ipv4_udp_tmplt},
 	{iavf_pattern_eth_ipv6_gre_ipv4_udp,	IAVF_RSS_TYPE_INNER_IPV4_UDP, &inner_ipv4_udp_tmplt},
+	{iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv4,	IAVF_RSS_TYPE_INNER_IPV4,	&udp_l2tpv2_ppp_ipv4_tmplt},
+	{iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv4_udp,	IAVF_RSS_TYPE_INNER_IPV4_UDP,	&udp_l2tpv2_ppp_ipv4_udp_tmplt},
+	{iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv4_tcp,	IAVF_RSS_TYPE_INNER_IPV4_TCP,	&udp_l2tpv2_ppp_ipv4_tcp_tmplt},
+	{iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv4,	IAVF_RSS_TYPE_INNER_IPV4,	&udp_l2tpv2_ppp_ipv4_tmplt},
+	{iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv4_udp,	IAVF_RSS_TYPE_INNER_IPV4_UDP,	&udp_l2tpv2_ppp_ipv4_udp_tmplt},
+	{iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv4_tcp,	IAVF_RSS_TYPE_INNER_IPV4_TCP,	&udp_l2tpv2_ppp_ipv4_tcp_tmplt},
+
 	/* IPv6 */
 	{iavf_pattern_eth_ipv6,				IAVF_RSS_TYPE_OUTER_IPV6,	&outer_ipv6_tmplt},
 	{iavf_pattern_eth_ipv6_frag_ext,		IAVF_RSS_TYPE_OUTER_IPV6_FRAG,	&outer_ipv6_frag_tmplt},
@@ -553,6 +614,13 @@ static struct iavf_pattern_match_item iavf_hash_pattern_list[] = {
 	{iavf_pattern_eth_ipv6_gre_ipv6_tcp,	IAVF_RSS_TYPE_INNER_IPV6_TCP, &inner_ipv6_tcp_tmplt},
 	{iavf_pattern_eth_ipv4_gre_ipv6_udp,	IAVF_RSS_TYPE_INNER_IPV6_UDP, &inner_ipv6_udp_tmplt},
 	{iavf_pattern_eth_ipv6_gre_ipv6_udp,	IAVF_RSS_TYPE_INNER_IPV6_UDP, &inner_ipv6_udp_tmplt},
+	{iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv6,	IAVF_RSS_TYPE_INNER_IPV6,	&udp_l2tpv2_ppp_ipv6_tmplt},
+	{iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv6_udp,	IAVF_RSS_TYPE_INNER_IPV6_UDP,	&udp_l2tpv2_ppp_ipv6_udp_tmplt},
+	{iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv6_tcp,	IAVF_RSS_TYPE_INNER_IPV6_TCP,	&udp_l2tpv2_ppp_ipv6_tcp_tmplt},
+	{iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv6,	IAVF_RSS_TYPE_INNER_IPV6,	&udp_l2tpv2_ppp_ipv6_tmplt},
+	{iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv6_udp,	IAVF_RSS_TYPE_INNER_IPV6_UDP,	&udp_l2tpv2_ppp_ipv6_udp_tmplt},
+	{iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv6_tcp,	IAVF_RSS_TYPE_INNER_IPV6_TCP,	&udp_l2tpv2_ppp_ipv6_tcp_tmplt},
+
 };
 
 static struct iavf_flow_engine iavf_hash_engine = {
@@ -687,13 +755,17 @@ iavf_hash_parse_pattern(const struct rte_flow_item pattern[], uint64_t *phint,
 
 		switch (item->type) {
 		case RTE_FLOW_ITEM_TYPE_IPV4:
-			if (!(*phint & IAVF_PHINT_GTPU_MSK) && !(*phint & IAVF_PHINT_GRE))
+			if (!(*phint & IAVF_PHINT_GTPU_MSK) &&
+			    !(*phint & IAVF_PHINT_GRE) &&
+			    !(*phint & IAVF_PHINT_L2TPV2))
 				*phint |= IAVF_PHINT_OUTER_IPV4;
 			if ((*phint & IAVF_PHINT_GRE) && !(*phint & IAVF_PHINT_GTPU_MSK))
 				*phint |= IAVF_PHINT_MID_IPV4;
 			break;
 		case RTE_FLOW_ITEM_TYPE_IPV6:
-			if (!(*phint & IAVF_PHINT_GTPU_MSK) && !(*phint & IAVF_PHINT_GRE))
+			if (!(*phint & IAVF_PHINT_GTPU_MSK) &&
+			    !(*phint & IAVF_PHINT_GRE) &&
+			    !(*phint & IAVF_PHINT_L2TPV2))
 				*phint |= IAVF_PHINT_OUTER_IPV6;
 			if ((*phint & IAVF_PHINT_GRE) && !(*phint & IAVF_PHINT_GTPU_MSK))
 				*phint |= IAVF_PHINT_MID_IPV6;
@@ -728,6 +800,10 @@ iavf_hash_parse_pattern(const struct rte_flow_item pattern[], uint64_t *phint,
 			break;
 		case RTE_FLOW_ITEM_TYPE_GRE:
 			*phint |= IAVF_PHINT_GRE;
+			break;
+		case RTE_FLOW_ITEM_TYPE_L2TPV2:
+			*phint |= IAVF_PHINT_L2TPV2;
+			break;
 		default:
 			break;
 		}
@@ -1050,12 +1126,40 @@ iavf_refine_proto_hdrs_by_pattern(struct virtchnl_proto_hdrs *proto_hdrs,
 	proto_hdrs->tunnel_level = tun_lvl;
 }
 
+static void
+iavf_refine_proto_hdrs_l2tpv2(struct virtchnl_proto_hdrs *proto_hdrs,
+			      uint64_t phint)
+{
+	struct virtchnl_proto_hdr *hdr1;
+	int i;
+
+	if (!(phint & IAVF_PHINT_L2TPV2))
+		return;
+
+	if (proto_hdrs->tunnel_level == TUNNEL_LEVEL_INNER) {
+		/* shift headers layer */
+		for (i = proto_hdrs->count - 1 + 1; i > 0; i--)
+			proto_hdrs->proto_hdr[i] = proto_hdrs->proto_hdr[i - 1];
+
+		/* adding outer ip header at layer 0 */
+		hdr1 = &proto_hdrs->proto_hdr[0];
+		hdr1->field_selector = 0;
+		proto_hdrs->count++;
+		proto_hdrs->tunnel_level = TUNNEL_LEVEL_OUTER;
+		if (phint & IAVF_PHINT_OUTER_IPV4)
+			VIRTCHNL_SET_PROTO_HDR_TYPE(hdr1, IPV4);
+		else if (phint & IAVF_PHINT_OUTER_IPV6)
+			VIRTCHNL_SET_PROTO_HDR_TYPE(hdr1, IPV6);
+	}
+}
+
 static void iavf_refine_proto_hdrs(struct virtchnl_proto_hdrs *proto_hdrs,
 				   uint64_t rss_type, uint64_t phint)
 {
 	iavf_refine_proto_hdrs_l234(proto_hdrs, rss_type);
 	iavf_refine_proto_hdrs_by_pattern(proto_hdrs, phint);
 	iavf_refine_proto_hdrs_gtpu(proto_hdrs, rss_type);
+	iavf_refine_proto_hdrs_l2tpv2(proto_hdrs, phint);
 }
 
 static uint64_t invalid_rss_comb[] = {
-- 
2.25.1


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

* [dpdk-dev] [PATCH v7 3/3] app/testpmd: support L2TPv2 and PPP protocol pattern
  2021-10-21  6:26           ` [dpdk-dev] [PATCH v7 0/3] support PPPoL2TPv2oUDP RSS Hash Jie Wang
  2021-10-21  6:26             ` [dpdk-dev] [PATCH v7 1/3] ethdev: support L2TPv2 and PPP procotol Jie Wang
  2021-10-21  6:26             ` [dpdk-dev] [PATCH v7 2/3] net/iavf: support PPPoL2TPv2oUDP RSS Hash Jie Wang
@ 2021-10-21  6:26             ` Jie Wang
  2021-10-21 10:05             ` [dpdk-dev] [PATCH v8 0/3] support PPPoL2TPv2oUDP RSS Hash Jie Wang
  3 siblings, 0 replies; 71+ messages in thread
From: Jie Wang @ 2021-10-21  6:26 UTC (permalink / raw)
  To: dev
  Cc: orika, ferruh.yigit, thomas, andrew.rybchenko, xiaoyun.li,
	stevex.yang, jingjing.wu, beilei.xing, wenjun1.wu, qi.z.zhang,
	Jie Wang

Add support for test-pmd to parse protocol pattern L2TPv2 and PPP.

Signed-off-by: Wenjun Wu <wenjun1.wu@intel.com>
Signed-off-by: Jie Wang <jie1x.wang@intel.com>
---
 app/test-pmd/cmdline_flow.c                 | 251 ++++++++++++++++++++
 doc/guides/testpmd_app_ug/testpmd_funcs.rst |  28 +++
 2 files changed, 279 insertions(+)

diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
index 5437975837..d8218771fb 100644
--- a/app/test-pmd/cmdline_flow.c
+++ b/app/test-pmd/cmdline_flow.c
@@ -321,6 +321,23 @@ enum index {
 	ITEM_FLEX,
 	ITEM_FLEX_ITEM_HANDLE,
 	ITEM_FLEX_PATTERN_HANDLE,
+	ITEM_L2TPV2,
+	ITEM_L2TPV2_COMMON,
+	ITEM_L2TPV2_COMMON_TYPE,
+	ITEM_L2TPV2_COMMON_TYPE_DATA_L,
+	ITEM_L2TPV2_COMMON_TYPE_CTRL,
+	ITEM_L2TPV2_MSG_DATA_L_LENGTH,
+	ITEM_L2TPV2_MSG_DATA_L_TUNNEL_ID,
+	ITEM_L2TPV2_MSG_DATA_L_SESSION_ID,
+	ITEM_L2TPV2_MSG_CTRL_LENGTH,
+	ITEM_L2TPV2_MSG_CTRL_TUNNEL_ID,
+	ITEM_L2TPV2_MSG_CTRL_SESSION_ID,
+	ITEM_L2TPV2_MSG_CTRL_NS,
+	ITEM_L2TPV2_MSG_CTRL_NR,
+	ITEM_PPP,
+	ITEM_PPP_ADDR,
+	ITEM_PPP_CTRL,
+	ITEM_PPP_PROTO_ID,
 
 	/* Validate/create actions. */
 	ACTIONS,
@@ -1042,6 +1059,8 @@ static const enum index next_item[] = {
 	ITEM_PORT_REPRESENTOR,
 	ITEM_REPRESENTED_PORT,
 	ITEM_FLEX,
+	ITEM_L2TPV2,
+	ITEM_PPP,
 	END_SET,
 	ZERO,
 };
@@ -1429,6 +1448,31 @@ static const enum index item_flex[] = {
 	ZERO,
 };
 
+static const enum index item_l2tpv2[] = {
+	ITEM_L2TPV2_COMMON,
+	ITEM_NEXT,
+	ZERO,
+};
+
+static const enum index item_l2tpv2_common[] = {
+	ITEM_L2TPV2_COMMON_TYPE,
+	ZERO,
+};
+
+static const enum index item_l2tpv2_common_type[] = {
+	ITEM_L2TPV2_COMMON_TYPE_DATA_L,
+	ITEM_L2TPV2_COMMON_TYPE_CTRL,
+	ZERO,
+};
+
+static const enum index item_ppp[] = {
+	ITEM_PPP_ADDR,
+	ITEM_PPP_CTRL,
+	ITEM_PPP_PROTO_ID,
+	ITEM_NEXT,
+	ZERO,
+};
+
 static const enum index next_action[] = {
 	ACTION_END,
 	ACTION_VOID,
@@ -1815,6 +1859,9 @@ static int parse_vc_conf(struct context *, const struct token *,
 static int parse_vc_item_ecpri_type(struct context *, const struct token *,
 				    const char *, unsigned int,
 				    void *, unsigned int);
+static int parse_vc_item_l2tpv2_type(struct context *, const struct token *,
+				    const char *, unsigned int,
+				    void *, unsigned int);
 static int parse_vc_action_meter_color_type(struct context *,
 					const struct token *,
 					const char *, unsigned int, void *,
@@ -3789,6 +3836,153 @@ static const struct token token_list[] = {
 			     NEXT_ENTRY(ITEM_PARAM_IS)),
 		.args = ARGS(ARGS_ENTRY(struct rte_flow_item_flex, pattern)),
 	},
+	[ITEM_L2TPV2] = {
+		.name = "l2tpv2",
+		.help = "match L2TPv2 header",
+		.priv = PRIV_ITEM(L2TPV2, sizeof(struct rte_flow_item_l2tpv2)),
+		.next = NEXT(item_l2tpv2),
+		.call = parse_vc,
+	},
+	[ITEM_L2TPV2_COMMON] = {
+		.name = "common",
+		.help = "L2TPv2 common header",
+		.next = NEXT(item_l2tpv2_common),
+	},
+	[ITEM_L2TPV2_COMMON_TYPE] = {
+		.name = "type",
+		.help = "type of common header",
+		.next = NEXT(item_l2tpv2_common_type),
+		.args = ARGS(ARG_ENTRY_HTON(struct rte_flow_item_l2tpv2)),
+	},
+	[ITEM_L2TPV2_COMMON_TYPE_DATA_L] = {
+		.name = "data_l",
+		.help = "Type #6: data message with length option",
+		.next = NEXT(NEXT_ENTRY(ITEM_L2TPV2_MSG_DATA_L_LENGTH,
+					ITEM_L2TPV2_MSG_DATA_L_TUNNEL_ID,
+					ITEM_L2TPV2_MSG_DATA_L_SESSION_ID,
+					ITEM_NEXT)),
+		.call = parse_vc_item_l2tpv2_type,
+	},
+	[ITEM_L2TPV2_MSG_DATA_L_LENGTH] = {
+		.name = "length",
+		.help = "message length",
+		.next = NEXT(NEXT_ENTRY(ITEM_L2TPV2_MSG_DATA_L_LENGTH,
+					ITEM_L2TPV2_COMMON, ITEM_NEXT),
+			     NEXT_ENTRY(COMMON_UNSIGNED),
+			     item_param),
+		.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2,
+					     hdr.type6.length)),
+	},
+	[ITEM_L2TPV2_MSG_DATA_L_TUNNEL_ID] = {
+		.name = "tunnel_id",
+		.help = "tunnel identifier",
+		.next = NEXT(NEXT_ENTRY(ITEM_L2TPV2_MSG_DATA_L_TUNNEL_ID,
+					ITEM_L2TPV2_COMMON, ITEM_NEXT),
+			     NEXT_ENTRY(COMMON_UNSIGNED),
+			     item_param),
+		.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2,
+					     hdr.type6.tunnel_id)),
+	},
+	[ITEM_L2TPV2_MSG_DATA_L_SESSION_ID] = {
+		.name = "session_id",
+		.help = "session identifier",
+		.next = NEXT(NEXT_ENTRY(ITEM_L2TPV2_MSG_DATA_L_SESSION_ID,
+					ITEM_L2TPV2_COMMON, ITEM_NEXT),
+			     NEXT_ENTRY(COMMON_UNSIGNED),
+			     item_param),
+		.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2,
+					     hdr.type6.session_id)),
+	},
+	[ITEM_L2TPV2_COMMON_TYPE_CTRL] = {
+		.name = "control",
+		.help = "Type #3: conrtol message contains length, ns, nr options",
+		.next = NEXT(NEXT_ENTRY(ITEM_L2TPV2_MSG_CTRL_LENGTH,
+					ITEM_L2TPV2_MSG_CTRL_TUNNEL_ID,
+					ITEM_L2TPV2_MSG_CTRL_SESSION_ID,
+					ITEM_L2TPV2_MSG_CTRL_NS,
+					ITEM_L2TPV2_MSG_CTRL_NR,
+					ITEM_NEXT)),
+		.call = parse_vc_item_l2tpv2_type,
+	},
+	[ITEM_L2TPV2_MSG_CTRL_LENGTH] = {
+		.name = "length",
+		.help = "message length",
+		.next = NEXT(NEXT_ENTRY(ITEM_L2TPV2_MSG_CTRL_LENGTH,
+					ITEM_L2TPV2_COMMON, ITEM_NEXT),
+			     NEXT_ENTRY(COMMON_UNSIGNED),
+			     item_param),
+		.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2,
+					     hdr.type3.length)),
+	},
+	[ITEM_L2TPV2_MSG_CTRL_TUNNEL_ID] = {
+		.name = "tunnel_id",
+		.help = "tunnel identifier",
+		.next = NEXT(NEXT_ENTRY(ITEM_L2TPV2_MSG_CTRL_TUNNEL_ID,
+					ITEM_L2TPV2_COMMON, ITEM_NEXT),
+			     NEXT_ENTRY(COMMON_UNSIGNED),
+			     item_param),
+		.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2,
+					     hdr.type3.tunnel_id)),
+	},
+	[ITEM_L2TPV2_MSG_CTRL_SESSION_ID] = {
+		.name = "session_id",
+		.help = "session identifier",
+		.next = NEXT(NEXT_ENTRY(ITEM_L2TPV2_MSG_CTRL_SESSION_ID,
+					ITEM_L2TPV2_COMMON, ITEM_NEXT),
+			     NEXT_ENTRY(COMMON_UNSIGNED),
+			     item_param),
+		.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2,
+					     hdr.type3.session_id)),
+	},
+	[ITEM_L2TPV2_MSG_CTRL_NS] = {
+		.name = "ns",
+		.help = "sequence number for message",
+		.next = NEXT(NEXT_ENTRY(ITEM_L2TPV2_MSG_CTRL_NS,
+					ITEM_L2TPV2_COMMON, ITEM_NEXT),
+			     NEXT_ENTRY(COMMON_UNSIGNED),
+			     item_param),
+		.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2,
+					     hdr.type3.ns)),
+	},
+	[ITEM_L2TPV2_MSG_CTRL_NR] = {
+		.name = "nr",
+		.help = "sequence number for next receive message",
+		.next = NEXT(NEXT_ENTRY(ITEM_L2TPV2_MSG_CTRL_NS,
+					ITEM_L2TPV2_COMMON, ITEM_NEXT),
+			     NEXT_ENTRY(COMMON_UNSIGNED),
+			     item_param),
+		.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2,
+					     hdr.type3.nr)),
+	},
+	[ITEM_PPP] = {
+		.name = "ppp",
+		.help = "match PPP header",
+		.priv = PRIV_ITEM(PPP, sizeof(struct rte_flow_item_ppp)),
+		.next = NEXT(item_ppp),
+		.call = parse_vc,
+	},
+	[ITEM_PPP_ADDR] = {
+		.name = "addr",
+		.help = "PPP address",
+		.next = NEXT(item_ppp, NEXT_ENTRY(COMMON_UNSIGNED),
+			     item_param),
+		.args = ARGS(ARGS_ENTRY(struct rte_flow_item_ppp, hdr.addr)),
+	},
+	[ITEM_PPP_CTRL] = {
+		.name = "ctrl",
+		.help = "PPP control",
+		.next = NEXT(item_ppp, NEXT_ENTRY(COMMON_UNSIGNED),
+			     item_param),
+		.args = ARGS(ARGS_ENTRY(struct rte_flow_item_ppp, hdr.ctrl)),
+	},
+	[ITEM_PPP_PROTO_ID] = {
+		.name = "proto_id",
+		.help = "PPP protocol identifier",
+		.next = NEXT(item_ppp, NEXT_ENTRY(COMMON_UNSIGNED),
+			     item_param),
+		.args = ARGS(ARGS_ENTRY(struct rte_flow_item_ppp,
+					hdr.proto_id)),
+	},
 	/* Validate/create actions. */
 	[ACTIONS] = {
 		.name = "actions",
@@ -5676,6 +5870,57 @@ parse_vc_item_ecpri_type(struct context *ctx, const struct token *token,
 	return len;
 }
 
+/** Parse L2TPv2 common header type field. */
+static int
+parse_vc_item_l2tpv2_type(struct context *ctx, const struct token *token,
+			 const char *str, unsigned int len,
+			 void *buf, unsigned int size)
+{
+	struct rte_flow_item_l2tpv2 *l2tpv2;
+	struct rte_flow_item_l2tpv2 *l2tpv2_mask;
+	struct rte_flow_item *item;
+	uint32_t data_size;
+	uint8_t msg_type = 0;
+	struct buffer *out = buf;
+	const struct arg *arg;
+
+	(void)size;
+	/* Token name must match. */
+	if (parse_default(ctx, token, str, len, NULL, 0) < 0)
+		return -1;
+	switch (ctx->curr) {
+	case ITEM_L2TPV2_COMMON_TYPE_DATA_L:
+		msg_type |= 0x4000;
+		break;
+	case ITEM_L2TPV2_COMMON_TYPE_CTRL:
+		msg_type |= 0xC800;
+		break;
+	default:
+		return -1;
+	}
+	if (!ctx->object)
+		return len;
+	arg = pop_args(ctx);
+	if (!arg)
+		return -1;
+	l2tpv2 = (struct rte_flow_item_l2tpv2 *)out->args.vc.data;
+	l2tpv2->hdr.common.flags_version |= msg_type;
+	data_size = ctx->objdata / 3; /* spec, last, mask */
+	l2tpv2_mask = (struct rte_flow_item_l2tpv2 *)(out->args.vc.data +
+						    (data_size * 2));
+	l2tpv2_mask->hdr.common.flags_version = 0xFFFF;
+	if (arg->hton) {
+		l2tpv2->hdr.common.flags_version =
+			rte_cpu_to_be_16(l2tpv2->hdr.common.flags_version);
+		l2tpv2_mask->hdr.common.flags_version =
+		    rte_cpu_to_be_16(l2tpv2_mask->hdr.common.flags_version);
+	}
+	item = &out->args.vc.pattern[out->args.vc.pattern_n - 1];
+	item->spec = l2tpv2;
+	item->mask = l2tpv2_mask;
+	return len;
+}
+
 /** Parse meter color action type. */
 static int
 parse_vc_action_meter_color_type(struct context *ctx, const struct token *token,
@@ -8701,6 +8946,12 @@ flow_item_default_mask(const struct rte_flow_item *item)
 	case RTE_FLOW_ITEM_TYPE_REPRESENTED_PORT:
 		mask = &rte_flow_item_ethdev_mask;
 		break;
+	case RTE_FLOW_ITEM_TYPE_L2TPV2:
+		mask = &rte_flow_item_l2tpv2_mask;
+		break;
+	case RTE_FLOW_ITEM_TYPE_PPP:
+		mask = &rte_flow_item_ppp_mask;
+		break;
 	default:
 		break;
 	}
diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
index 6d127d9a7b..31d6e1b293 100644
--- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
+++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
@@ -3810,6 +3810,20 @@ This section lists supported pattern items and their attributes, if any.
 
   - ``ethdev_port_id {unsigned}``: ethdev port ID
 
+- ``l2tpv2``: match L2TPv2 header.
+
+  - ``length {unsigned}``: L2TPv2 option length.
+  - ``tunnel_id {unsigned}``: L2TPv2 tunnel identifier.
+  - ``session_id {unsigned}``: L2TPv2 session identifier.
+  - ``ns {unsigned}``: L2TPv2 option ns.
+  - ``nr {unsigned}``: L2TPv2 option nr.
+
+- ``ppp``: match PPP header.
+
+  - ``addr {unsigned}``: PPP address.
+  - ``ctrl {unsigned}``: PPP control.
+  - ``proto_id {unsigned}``: PPP protocol identifier.
+
 Actions list
 ^^^^^^^^^^^^
 
@@ -5036,6 +5050,20 @@ The meter policy action list: ``green -> green, yellow -> yellow, red -> red``.
    testpmd> create port meter 0 1 13 1 yes 0xffff 0 0
    testpmd> flow create 0 priority 0 ingress group 1 pattern eth / end actions meter mtr_id 1 / end
 
+Sample PPPoL2TPv2oUDP RSS rules
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+PPPoL2TPv2oUDP RSS rules can be created by the following commands::
+
+ testpmd> flow create 0 ingress pattern eth / ipv4 / udp / l2tpv2 / ppp / ipv4
+          / end actions rss types ipv4 end queues end / end
+ testpmd> flow create 0 ingress pattern eth / ipv4 / udp / l2tpv2 / ppp / ipv6
+          / udp / end actions rss types ipv6-udp end queues end / end
+ testpmd> flow create 0 ingress pattern eth / ipv6 / udp / l2tpv2 / ppp / ipv4
+          / tcp / end actions rss types ipv4-tcp end queues end / end
+ testpmd> flow create 0 ingress pattern eth / ipv6 / udp / l2tpv2 / ppp / ipv6
+          / end actions rss types ipv6 end queues end / end
+
 BPF Functions
 --------------
 
-- 
2.25.1


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

* Re: [dpdk-dev] [PATCH v7 1/3] ethdev: support L2TPv2 and PPP procotol
  2021-10-21  6:26             ` [dpdk-dev] [PATCH v7 1/3] ethdev: support L2TPv2 and PPP procotol Jie Wang
@ 2021-10-21  7:50               ` Ori Kam
  2021-10-21  7:52                 ` Andrew Rybchenko
                                   ` (2 more replies)
  2021-10-21  9:29               ` Ferruh Yigit
  1 sibling, 3 replies; 71+ messages in thread
From: Ori Kam @ 2021-10-21  7:50 UTC (permalink / raw)
  To: Jie Wang, dev
  Cc: ferruh.yigit, NBU-Contact-Thomas Monjalon, andrew.rybchenko,
	xiaoyun.li, stevex.yang, jingjing.wu, beilei.xing, wenjun1.wu,
	qi.z.zhang

Hi Jie,

> -----Original Message-----
> From: Jie Wang <jie1x.wang@intel.com>
> Sent: Thursday, October 21, 2021 9:26 AM
> Subject: [PATCH v7 1/3] ethdev: support L2TPv2 and PPP procotol
> 
> Added flow pattern items and header formats of L2TPv2 and PPP.
> 
> Signed-off-by: Wenjun Wu <wenjun1.wu@intel.com>
> Signed-off-by: Jie Wang <jie1x.wang@intel.com>
> ---
>  doc/api/doxy-api-index.md              |   2 +
>  doc/guides/nics/features/default.ini   |   2 +
>  doc/guides/nics/features/iavf.ini      |   2 +
>  doc/guides/prog_guide/rte_flow.rst     |  25 +++
>  doc/guides/rel_notes/release_21_11.rst |   4 +
>  lib/ethdev/rte_flow.c                  |   2 +
>  lib/ethdev/rte_flow.h                  |  65 +++++++
>  lib/net/meson.build                    |   2 +
>  lib/net/rte_l2tpv2.h                   | 234 +++++++++++++++++++++++++
>  lib/net/rte_ppp.h                      |  34 ++++
>  10 files changed, 372 insertions(+)
>  create mode 100644 lib/net/rte_l2tpv2.h
>  create mode 100644 lib/net/rte_ppp.h
> 
> diff --git a/doc/api/doxy-api-index.md b/doc/api/doxy-api-index.md
> index 1992107a03..42db196afe 100644
> --- a/doc/api/doxy-api-index.md
> +++ b/doc/api/doxy-api-index.md
> @@ -121,6 +121,8 @@ The public API headers are grouped by topics:
>    [VXLAN]              (@ref rte_vxlan.h),
>    [Geneve]             (@ref rte_geneve.h),
>    [eCPRI]              (@ref rte_ecpri.h)
> +  [L2TPv2]             (@ref rte_l2tpv2.h)
> +  [PPP]                (@ref rte_ppp.h)
> 
>  - **QoS**:
>    [metering]           (@ref rte_meter.h),
> diff --git a/doc/guides/nics/features/default.ini b/doc/guides/nics/features/default.ini
> index 09914b1ad3..8e6a28c419 100644
> --- a/doc/guides/nics/features/default.ini
> +++ b/doc/guides/nics/features/default.ini
> @@ -110,6 +110,7 @@ ipv4                 =
>  ipv6                 =
>  ipv6_ext             =
>  ipv6_frag_ext        =
> +l2tpv2               =
>  l2tpv3oip            =
>  mark                 =
>  meta                 =
> @@ -121,6 +122,7 @@ pfcp                 =
>  phy_port             =
>  port_id              =
>  port_representor     =
> +ppp                  =
>  pppoed               =
>  pppoes               =
>  pppoe_proto_id       =
> diff --git a/doc/guides/nics/features/iavf.ini b/doc/guides/nics/features/iavf.ini
> index d00ca934c3..a916275b88 100644
> --- a/doc/guides/nics/features/iavf.ini
> +++ b/doc/guides/nics/features/iavf.ini
> @@ -50,8 +50,10 @@ icmp6                = Y
>  ipv4                 = Y
>  ipv6                 = Y
>  ipv6_frag_ext        = Y
> +l2tpv2               = Y
>  l2tpv3oip            = Y
>  pfcp                 = Y
> +ppp                  = Y
>  sctp                 = Y
>  tcp                  = Y
>  udp                  = Y
> diff --git a/doc/guides/prog_guide/rte_flow.rst b/doc/guides/prog_guide/rte_flow.rst
> index aeba374182..a2169517c3 100644
> --- a/doc/guides/prog_guide/rte_flow.rst
> +++ b/doc/guides/prog_guide/rte_flow.rst
> @@ -1573,6 +1573,31 @@ rte_flow_flex_item_create() routine.
>    as padded with trailing zeroes up to full configured length, both for
>    value and mask.
> 
> +Item: ``L2TPV2``
> +^^^^^^^^^^^^^^^^^^^
> +
> +Matches a L2TPv2 header.
> +
> +- ``flags_version``: flags(12b), version(4b).
> +- ``length``: total length of the message.
> +- ``tunnel_id``: identifier for the control connection.
> +- ``session_id``: identifier for a session within a tunnel.
> +- ``ns``: sequence number for this date or control message.
> +- ``nr``: sequence number expected in the next control message to be received.
> +- ``offset_size``: offset of payload data.
> +- ``offset_padding``: offset padding, variable length.
> +- Default ``mask`` matches flags_version only.
> +
> +Item: ``PPP``
> +^^^^^^^^^^^^^^^^^^^
> +
> +Matches a PPP header.
> +
> +- ``addr``: PPP address.
> +- ``ctrl``: PPP control.
> +- ``proto_id``: PPP protocol identifier.
> +- Default ``mask`` matches addr, ctrl, proto_id.
> +
>  Actions
>  ~~~~~~~
> 
> diff --git a/doc/guides/rel_notes/release_21_11.rst b/doc/guides/rel_notes/release_21_11.rst
> index 041383ee2a..283770131c 100644
> --- a/doc/guides/rel_notes/release_21_11.rst
> +++ b/doc/guides/rel_notes/release_21_11.rst
> @@ -105,6 +105,10 @@ New Features
> 
>    Added an ethdev API which can help users get device configuration.
> 
> +* **Added L2TPv2 and PPP protocol support in rte_flow.**
> +
> +  Added flow pattern items and header formats of L2TPv2 and PPP protocol.
> +
>  * **Updated AF_XDP PMD.**
> 
>    * Disabled secondary process support.
> diff --git a/lib/ethdev/rte_flow.c b/lib/ethdev/rte_flow.c
> index bcf0513b3c..d268784532 100644
> --- a/lib/ethdev/rte_flow.c
> +++ b/lib/ethdev/rte_flow.c
> @@ -156,6 +156,8 @@ static const struct rte_flow_desc_data rte_flow_desc_item[] = {
>  	MK_FLOW_ITEM(REPRESENTED_PORT, sizeof(struct rte_flow_item_ethdev)),
>  	MK_FLOW_ITEM_FN(FLEX, sizeof(struct rte_flow_item_flex),
>  			rte_flow_item_flex_conv),
> +	MK_FLOW_ITEM(L2TPV2, sizeof(struct rte_flow_item_l2tpv2)),
> +	MK_FLOW_ITEM(PPP, sizeof(struct rte_flow_item_ppp)),
>  };
> 
>  /** Generate flow_action[] entry. */
> diff --git a/lib/ethdev/rte_flow.h b/lib/ethdev/rte_flow.h
> index 64ed7f2618..300e99e16b 100644
> --- a/lib/ethdev/rte_flow.h
> +++ b/lib/ethdev/rte_flow.h
> @@ -35,6 +35,8 @@
>  #include <rte_mbuf_dyn.h>
>  #include <rte_meter.h>
>  #include <rte_gtp.h>
> +#include <rte_l2tpv2.h>
> +#include <rte_ppp.h>
> 
>  #ifdef __cplusplus
>  extern "C" {
> @@ -644,6 +646,20 @@ enum rte_flow_item_type {
>  	 * @see struct rte_flow_item_flex.
>  	 */
>  	RTE_FLOW_ITEM_TYPE_FLEX,
> +
> +	/**
> +	 * Matches L2TPv2 Header.
> +	 *
> +	 * See struct rte_flow_item_l2tpv2.
> +	 */
> +	RTE_FLOW_ITEM_TYPE_L2TPV2,
> +
> +	/**
> +	 * Matches PPP Header.
> +	 *
> +	 * See struct rte_flow_item_ppp.
> +	 */
> +	RTE_FLOW_ITEM_TYPE_PPP,
>  };
> 
>  /**
> @@ -1900,6 +1916,55 @@ static const struct rte_flow_item_ethdev rte_flow_item_ethdev_mask = {
>  };
>  #endif
> 
> +/**
> + * @warning
> + * @b EXPERIMENTAL: this structure may change without prior notice
> + * RTE_FLOW_ITEM_TYPE_L2TPV2
> + *
> + * Matches L2TPv2 Header
> + */
> +struct rte_flow_item_l2tpv2 {
> +	struct rte_l2tpv2_combined_msg_hdr hdr;
> +};
> +
> +/** Default mask for RTE_FLOW_ITEM_TYPE_L2TPV2. */
> +#ifndef __cplusplus
> +static const struct rte_flow_item_l2tpv2 rte_flow_item_l2tpv2_mask = {
> +	/*
> +	 * flags and version bit mask
> +	 * 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0
> +	 * T L x x S x O P x x x x V V V V
> +	 */
> +	.hdr = {
> +		.common = {
> +			.flags_version = RTE_BE16(0xcb0f),
> +		},
> +	},
> +};
> +#endif
> +
> +/**
> + * @warning
> + * @b EXPERIMENTAL: this structure may change without prior notice
> + * RTE_FLOW_ITEM_TYPE_PPP
> + *
> + * Matches PPP Header
> + */
> +struct rte_flow_item_ppp {
> +	struct rte_ppp_hdr hdr;
> +};
> +
> +/** Default mask for RTE_FLOW_ITEM_TYPE_PPP. */
> +#ifndef __cplusplus
> +static const struct rte_flow_item_ppp rte_flow_item_ppp_mask = {
> +	.hdr = {
> +		.addr = 0xff,
> +		.ctrl = 0xff,
> +		.proto_id = RTE_BE16(0xffff),
> +	}
> +};
> +#endif
> +
>  /**
>   * Matching pattern item definition.
>   *
> diff --git a/lib/net/meson.build b/lib/net/meson.build
> index a4e395e9c5..e899846578 100644
> --- a/lib/net/meson.build
> +++ b/lib/net/meson.build
> @@ -19,6 +19,8 @@ headers = files(
>          'rte_higig.h',
>          'rte_ecpri.h',
>          'rte_geneve.h',
> +        'rte_l2tpv2.h',
> +        'rte_ppp.h',
>  )
> 
>  sources = files(
> diff --git a/lib/net/rte_l2tpv2.h b/lib/net/rte_l2tpv2.h
> new file mode 100644
> index 0000000000..18ea759ff4
> --- /dev/null
> +++ b/lib/net/rte_l2tpv2.h
> @@ -0,0 +1,234 @@
> +/* SPDX-License-Identifier: BSD-3-Clause
> + * Copyright 2021 Mellanox Technologies, Ltd
> + */
> +
> +#ifndef _RTE_L2TPV2_H_
> +#define _RTE_L2TPV2_H_
> +
> +/**
> + * @file
> + *
> + * L2TP header:
> + *
> + * `-0--------------------1----------------2-------------------3`
> + *
> + * `-0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1`
> + *
> + * `+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+`
> + *
> + * `|T|L|x|x|S|x|O|P|x|x|x|x|--Ver--|-----------Length (opt)--------|`
> + *
> + * `+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+`
> + *
> + * `|-----------Tunnel ID-----------|-----------Session ID----------|`
> + *
> + * `+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+`
> + *
> + * `|-----------Ns (opt)------------|-----------Nr (opt)------------|`
> + *
> + * `+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+`
> + *
> + * `|---------Offset Size (opt)-----|---------Offset pad... (opt)`
> + *
> + * `+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+`
> + *
> + * The Type (T) bit indicates the type of message. It is set to 0 for a data
> + * message and 1 for a control message.
> + *
> + * If the Length (L) bit is 1, the Length field is present. This bit MUST be
> + * set to 1 for control messages.
> + *
> + * The x bits are reserved for future extensions. All reserved bits MUST
> + * be set to 0 on outgoing messages and ignored on incoming messages.
> + *
> + * If the Sequence (S) bit is set to 1 the Ns and Nr fields are present.
> + * The S bit MUST be set to 1 for control messages.
> + *
> + * If the Offset (O) bit is 1, the Offset Size field is present. The O
> + * bit MUST be set to 0 for control messages.
> + *
> + * If the Priority (P) bit is 1, this data message should receive
> + * preferential treatment in its local queuing and transmission.
> + * The P bit MUST be set to 0 for control messages.
> + *
> + * Ver MUST be 2, indicating the version of the L2TP data message header.
> + *
> + * The Length field indicates the total length of the message in octets.
> + *
> + * Tunnel ID indicates the identifier for the control connection.
> + *
> + * Session ID indicates the identifier for a session within a tunnel.
> + *
> + * Ns indicates the sequence number for this data or control message.
> + *
> + * Nr indicates the sequence number expected in the next control message
> + * to be received.
> + *
> + * The Offset Size field, if present, specifies the number of octets
> + * past the L2TP header at which the payload data is expected to start.
> + * Actual data within the offset padding is undefined. If the offset
> + * field is present, the L2TP header ends after the last octet of the
> + * offset padding.
> + */
> +
> +#include <stdint.h>
> +#include <rte_byteorder.h>
> +
> +#ifdef __cplusplus
> +extern "C" {
> +#endif
> +
> +/**
> + * L2TPv2 Common Header
> + */
> +RTE_STD_C11
> +struct rte_l2tpv2_common_hdr {
> +	union {
> +		/** header flags and protocol version */
> +		rte_be16_t flags_version;
> +		struct {
> +#if RTE_BYTE_ORDER == RTE_LITTLE_ENDIAN
> +			rte_be16_t t:1;		/**< message Type */
> +			rte_be16_t l:1;		/**< length option bit */
> +			rte_be16_t res1:2;	/**< reserved */
> +			rte_be16_t s:1;		/**< ns/nr option bit */
> +			rte_be16_t res2:1;	/**< reserved */
> +			rte_be16_t o:1;		/**< offset option bit */
> +			rte_be16_t p:1;		/**< priority option bit */
> +			rte_be16_t res3:4;	/**< reserved */
> +			rte_be16_t ver:4;	/**< protocol version */
> +#elif RTE_BYTE_ORDER == RTE_BIG_ENDIAN
> +			rte_be16_t ver:4;	/**< protocol version */
> +			rte_be16_t res3:4;	/**< reserved */
> +			rte_be16_t p:1;		/**< priority option bit */
> +			rte_be16_t o:1;		/**< offset option bit */
> +			rte_be16_t res2:1;	/**< reserved */
> +			rte_be16_t s:1;		/**< ns/nr option bit */
> +			rte_be16_t res1:2;	/**< reserved */
> +			rte_be16_t l:1;		/**< length option bit */
> +			rte_be16_t t:1;		/**< message Type */
> +#endif
> +		};
> +	};
> +};
> +
> +/**
> + * L2TPv2 message Header contains all options(length, ns, nr,
> + * offset size, offset padding).
> + */
> +struct rte_l2tpv2_msg_with_all_options {
> +	rte_be16_t length;		/**< length(16) */
> +	rte_be16_t tunnel_id;		/**< tunnel ID(16) */
> +	rte_be16_t session_id;		/**< session ID(16) */
> +	rte_be16_t ns;			/**< Ns(16) */
> +	rte_be16_t nr;			/**< Nr(16) */
> +	rte_be16_t offset_size;		/**< offset size(16) */
> +	uint8_t   *offset_padding;	/**< offset padding(variable length) */
> +};
> +
> +/**
> + * L2TPv2 message Header contains all options except length(ns, nr,
> + * offset size, offset padding).
> + */
> +struct rte_l2tpv2_msg_without_length {
> +	rte_be16_t tunnel_id;		/**< tunnel ID(16) */
> +	rte_be16_t session_id;		/**< session ID(16) */
> +	rte_be16_t ns;			/**< Ns(16) */
> +	rte_be16_t nr;			/**< Nr(16) */
> +	rte_be16_t offset_size;		/**< offset size(16) */
> +	uint8_t   *offset_padding;	/**< offset padding(variable length) */
> +};
> +
> +/**
> + * L2TPv2 message Header contains all options except ns_nr(length,
> + * offset size, offset padding).
> + * Ns and Nr MUST be toghter.
> + */
> +struct rte_l2tpv2_msg_without_ns_nr {
> +	rte_be16_t length;		/**< length(16) */
> +	rte_be16_t tunnel_id;		/**< tunnel ID(16) */
> +	rte_be16_t session_id;		/**< session ID(16) */
> +	rte_be16_t offset_size;		/**< offset size(16) */
> +	uint8_t   *offset_padding;	/**< offset padding(variable length) */
> +};
> +
> +/**
> + * L2TPv2 message Header contains all options except ns_nr(length, ns, nr).
> + * offset size and offset padding MUST be toghter.
> + */
> +struct rte_l2tpv2_msg_without_offset {
> +	rte_be16_t length;		/**< length(16) */
> +	rte_be16_t tunnel_id;		/**< tunnel ID(16) */
> +	rte_be16_t session_id;		/**< session ID(16) */
> +	rte_be16_t ns;			/**< Ns(16) */
> +	rte_be16_t nr;			/**< Nr(16) */
> +};

Why not packed?

> +
> +/**
> + * L2TPv2 message Header contains options offset size and offset padding.
> + */
> +struct rte_l2tpv2_msg_with_offset {
> +	rte_be16_t tunnel_id;		/**< tunnel ID(16) */
> +	rte_be16_t session_id;		/**< session ID(16) */
> +	rte_be16_t offset_size;		/**< offset size(16) */
> +	uint8_t   *offset_padding;	/**< offset padding(variable length) */
> +};
> +
> +/**
> + * L2TPv2 message Header contains options ns and nr.
> + */
> +struct rte_l2tpv2_msg_with_ns_nr {
> +	rte_be16_t tunnel_id;		/**< tunnel ID(16) */
> +	rte_be16_t session_id;		/**< session ID(16) */
> +	rte_be16_t ns;			/**< Ns(16) */
> +	rte_be16_t nr;			/**< Nr(16) */
> +};

Why not packed? Same for all structs.


> +
> +/**
> + * L2TPv2 message Header contains option length.
> + */
> +struct rte_l2tpv2_msg_with_length {
> +	rte_be16_t length;		/**< length(16) */
> +	rte_be16_t tunnel_id;		/**< tunnel ID(16) */
> +	rte_be16_t session_id;		/**< session ID(16) */
> +};
> +
> +/**
> + * L2TPv2 message Header without all options.
> + */
> +struct rte_l2tpv2_msg_without_all_options {
> +	rte_be16_t tunnel_id;		/**< tunnel ID(16) */
> +	rte_be16_t session_id;		/**< session ID(16) */
> +};
> +
> +/**
> + * L2TPv2 Combined Message Header Format: Common Header + Options
> + */
> +RTE_STD_C11
> +struct rte_l2tpv2_combined_msg_hdr {
> +	struct rte_l2tpv2_common_hdr common; /**< common header */
> +	union {
> +		/** header with all options */
> +		struct rte_l2tpv2_msg_with_all_options type0;
> +		/** header with all options except length */
> +		struct rte_l2tpv2_msg_without_length type1;
> +		/** header with all options except ns/nr */
> +		struct rte_l2tpv2_msg_without_ns_nr type2;
> +		/** header with all options except offset */
> +		struct rte_l2tpv2_msg_without_offset type3;
> +		/** header with offset options */
> +		struct rte_l2tpv2_msg_with_offset type4;
> +		/** header with ns/nr options */
> +		struct rte_l2tpv2_msg_with_ns_nr type5;
> +		/** header with length option */
> +		struct rte_l2tpv2_msg_with_length type6;
> +		/** header without all options */
> +		struct rte_l2tpv2_msg_without_all_options type7;
> +	};
> +};
> +
> +#ifdef __cplusplus
> +}
> +#endif
> +
> +#endif /* _RTE_L2TPV2_H_ */
> diff --git a/lib/net/rte_ppp.h b/lib/net/rte_ppp.h
> new file mode 100644
> index 0000000000..2a53cd969f
> --- /dev/null
> +++ b/lib/net/rte_ppp.h
> @@ -0,0 +1,34 @@
> +/* SPDX-License-Identifier: BSD-3-Clause
> + * Copyright 2021 Mellanox Technologies, Ltd
> + */
> +
> +#ifndef _RTE_PPP_H_
> +#define _RTE_PPP_H_
> +
> +/**
> + * @file
> + *
> + * PPP headers definition.
> + */
> +
> +#include <stdint.h>
> +#include <rte_byteorder.h>
> +
> +#ifdef __cplusplus
> +extern "C" {
> +#endif
> +
> +/**
> + * PPP Header
> + */
> +struct rte_ppp_hdr {
> +	uint8_t addr; /**< PPP address(8) */
> +	uint8_t ctrl; /**< PPP control(8) */
> +	rte_be16_t proto_id; /**< PPP protocol identifier(16) */
> +} __rte_packed;
> +
> +#ifdef __cplusplus
> +}
> +#endif
> +
> +#endif /* _RTE_PPP_H_ */
> --
> 2.25.1

Best,
Ori

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

* Re: [dpdk-dev] [PATCH v7 1/3] ethdev: support L2TPv2 and PPP procotol
  2021-10-21  7:50               ` Ori Kam
@ 2021-10-21  7:52                 ` Andrew Rybchenko
  2021-10-21  8:28                   ` Wang, Jie1X
  2021-10-21  8:41                 ` Wang, Jie1X
  2021-10-21  9:26                 ` Ferruh Yigit
  2 siblings, 1 reply; 71+ messages in thread
From: Andrew Rybchenko @ 2021-10-21  7:52 UTC (permalink / raw)
  To: Jie Wang, dev
  Cc: ferruh.yigit, NBU-Contact-Thomas Monjalon, xiaoyun.li,
	stevex.yang, jingjing.wu, beilei.xing, wenjun1.wu, qi.z.zhang,
	Ori Kam

On 10/21/21 10:50 AM, Ori Kam wrote:
> Hi Jie,
> 
>> -----Original Message-----
>> From: Jie Wang <jie1x.wang@intel.com>
>> Sent: Thursday, October 21, 2021 9:26 AM
>> Subject: [PATCH v7 1/3] ethdev: support L2TPv2 and PPP procotol
>>
>> Added flow pattern items and header formats of L2TPv2 and PPP.
>>
>> Signed-off-by: Wenjun Wu <wenjun1.wu@intel.com>
>> Signed-off-by: Jie Wang <jie1x.wang@intel.com>

[snip]

>> diff --git a/doc/guides/nics/features/iavf.ini b/doc/guides/nics/features/iavf.ini
>> index d00ca934c3..a916275b88 100644
>> --- a/doc/guides/nics/features/iavf.ini
>> +++ b/doc/guides/nics/features/iavf.ini
>> @@ -50,8 +50,10 @@ icmp6                = Y
>>  ipv4                 = Y
>>  ipv6                 = Y
>>  ipv6_frag_ext        = Y
>> +l2tpv2               = Y
>>  l2tpv3oip            = Y
>>  pfcp                 = Y
>> +ppp                  = Y

It must be added in the patch when driver support is added.

>>  sctp                 = Y
>>  tcp                  = Y
>>  udp                  = Y

[snip]

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

* Re: [dpdk-dev] [PATCH v7 1/3] ethdev: support L2TPv2 and PPP procotol
  2021-10-21  7:52                 ` Andrew Rybchenko
@ 2021-10-21  8:28                   ` Wang, Jie1X
  2021-10-21  8:30                     ` Andrew Rybchenko
  0 siblings, 1 reply; 71+ messages in thread
From: Wang, Jie1X @ 2021-10-21  8:28 UTC (permalink / raw)
  To: Andrew Rybchenko, dev
  Cc: Yigit, Ferruh, NBU-Contact-Thomas Monjalon, Li, Xiaoyun, Yang,
	SteveX, Wu, Jingjing, Xing, Beilei, Wu, Wenjun1, Zhang, Qi Z,
	Ori Kam



> -----Original Message-----
> From: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>
> Sent: Thursday, October 21, 2021 3:53 PM
> To: Wang, Jie1X <jie1x.wang@intel.com>; dev@dpdk.org
> Cc: Yigit, Ferruh <ferruh.yigit@intel.com>; NBU-Contact-Thomas Monjalon
> <thomas@monjalon.net>; Li, Xiaoyun <xiaoyun.li@intel.com>; Yang, SteveX
> <stevex.yang@intel.com>; Wu, Jingjing <jingjing.wu@intel.com>; Xing, Beilei
> <beilei.xing@intel.com>; Wu, Wenjun1 <wenjun1.wu@intel.com>; Zhang, Qi Z
> <qi.z.zhang@intel.com>; Ori Kam <orika@nvidia.com>
> Subject: Re: [PATCH v7 1/3] ethdev: support L2TPv2 and PPP procotol
> 
> On 10/21/21 10:50 AM, Ori Kam wrote:
> > Hi Jie,
> >
> >> -----Original Message-----
> >> From: Jie Wang <jie1x.wang@intel.com>
> >> Sent: Thursday, October 21, 2021 9:26 AM
> >> Subject: [PATCH v7 1/3] ethdev: support L2TPv2 and PPP procotol
> >>
> >> Added flow pattern items and header formats of L2TPv2 and PPP.
> >>
> >> Signed-off-by: Wenjun Wu <wenjun1.wu@intel.com>
> >> Signed-off-by: Jie Wang <jie1x.wang@intel.com>
> 
> [snip]
> 
> >> diff --git a/doc/guides/nics/features/iavf.ini
> b/doc/guides/nics/features/iavf.ini
> >> index d00ca934c3..a916275b88 100644
> >> --- a/doc/guides/nics/features/iavf.ini
> >> +++ b/doc/guides/nics/features/iavf.ini
> >> @@ -50,8 +50,10 @@ icmp6                = Y
> >>  ipv4                 = Y
> >>  ipv6                 = Y
> >>  ipv6_frag_ext        = Y
> >> +l2tpv2               = Y
> >>  l2tpv3oip            = Y
> >>  pfcp                 = Y
> >> +ppp                  = Y
> 
> It must be added in the patch when driver support is added.
> 

Hi Andrew,

I don't understand what you're saying. Could you describe it in more detail?

> >>  sctp                 = Y
> >>  tcp                  = Y
> >>  udp                  = Y
> 
> [snip]

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

* Re: [dpdk-dev] [PATCH v7 1/3] ethdev: support L2TPv2 and PPP procotol
  2021-10-21  8:28                   ` Wang, Jie1X
@ 2021-10-21  8:30                     ` Andrew Rybchenko
  0 siblings, 0 replies; 71+ messages in thread
From: Andrew Rybchenko @ 2021-10-21  8:30 UTC (permalink / raw)
  To: Wang, Jie1X, dev
  Cc: Yigit, Ferruh, NBU-Contact-Thomas Monjalon, Li, Xiaoyun, Yang,
	SteveX, Wu, Jingjing, Xing, Beilei, Wu, Wenjun1, Zhang, Qi Z,
	Ori Kam

On 10/21/21 11:28 AM, Wang, Jie1X wrote:
> 
> 
>> -----Original Message-----
>> From: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>
>> Sent: Thursday, October 21, 2021 3:53 PM
>> To: Wang, Jie1X <jie1x.wang@intel.com>; dev@dpdk.org
>> Cc: Yigit, Ferruh <ferruh.yigit@intel.com>; NBU-Contact-Thomas Monjalon
>> <thomas@monjalon.net>; Li, Xiaoyun <xiaoyun.li@intel.com>; Yang, SteveX
>> <stevex.yang@intel.com>; Wu, Jingjing <jingjing.wu@intel.com>; Xing, Beilei
>> <beilei.xing@intel.com>; Wu, Wenjun1 <wenjun1.wu@intel.com>; Zhang, Qi Z
>> <qi.z.zhang@intel.com>; Ori Kam <orika@nvidia.com>
>> Subject: Re: [PATCH v7 1/3] ethdev: support L2TPv2 and PPP procotol
>>
>> On 10/21/21 10:50 AM, Ori Kam wrote:
>>> Hi Jie,
>>>
>>>> -----Original Message-----
>>>> From: Jie Wang <jie1x.wang@intel.com>
>>>> Sent: Thursday, October 21, 2021 9:26 AM
>>>> Subject: [PATCH v7 1/3] ethdev: support L2TPv2 and PPP procotol
>>>>
>>>> Added flow pattern items and header formats of L2TPv2 and PPP.
>>>>
>>>> Signed-off-by: Wenjun Wu <wenjun1.wu@intel.com>
>>>> Signed-off-by: Jie Wang <jie1x.wang@intel.com>
>>
>> [snip]
>>
>>>> diff --git a/doc/guides/nics/features/iavf.ini
>> b/doc/guides/nics/features/iavf.ini
>>>> index d00ca934c3..a916275b88 100644
>>>> --- a/doc/guides/nics/features/iavf.ini
>>>> +++ b/doc/guides/nics/features/iavf.ini
>>>> @@ -50,8 +50,10 @@ icmp6                = Y
>>>>  ipv4                 = Y
>>>>  ipv6                 = Y
>>>>  ipv6_frag_ext        = Y
>>>> +l2tpv2               = Y
>>>>  l2tpv3oip            = Y
>>>>  pfcp                 = Y
>>>> +ppp                  = Y
>>
>> It must be added in the patch when driver support is added.
>>
> 
> Hi Andrew,
> 
> I don't understand what you're saying. Could you describe it in more detail?

The patch is an ethdev patch which defines the feature.
When just the patch is applied, the driver iavf does not
support it yet. Support is added in a later patch of the
patch series. So, you should claim support in the driver
when support is actually added.

> 
>>>>  sctp                 = Y
>>>>  tcp                  = Y
>>>>  udp                  = Y
>>
>> [snip]


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

* Re: [dpdk-dev] [PATCH v7 1/3] ethdev: support L2TPv2 and PPP procotol
  2021-10-21  7:50               ` Ori Kam
  2021-10-21  7:52                 ` Andrew Rybchenko
@ 2021-10-21  8:41                 ` Wang, Jie1X
  2021-10-21 13:18                   ` Ori Kam
  2021-10-21  9:26                 ` Ferruh Yigit
  2 siblings, 1 reply; 71+ messages in thread
From: Wang, Jie1X @ 2021-10-21  8:41 UTC (permalink / raw)
  To: Ori Kam, dev
  Cc: Yigit, Ferruh, NBU-Contact-Thomas Monjalon, andrew.rybchenko, Li,
	Xiaoyun, Yang,  SteveX, Wu, Jingjing, Xing, Beilei, Wu, Wenjun1,
	Zhang, Qi Z



> -----Original Message-----
> From: Ori Kam <orika@nvidia.com>
> Sent: Thursday, October 21, 2021 3:50 PM
> To: Wang, Jie1X <jie1x.wang@intel.com>; dev@dpdk.org
> Cc: Yigit, Ferruh <ferruh.yigit@intel.com>; NBU-Contact-Thomas Monjalon
> <thomas@monjalon.net>; andrew.rybchenko@oktetlabs.ru; Li, Xiaoyun
> <xiaoyun.li@intel.com>; Yang, SteveX <stevex.yang@intel.com>; Wu, Jingjing
> <jingjing.wu@intel.com>; Xing, Beilei <beilei.xing@intel.com>; Wu, Wenjun1
> <wenjun1.wu@intel.com>; Zhang, Qi Z <qi.z.zhang@intel.com>
> Subject: RE: [PATCH v7 1/3] ethdev: support L2TPv2 and PPP procotol
> 
> Hi Jie,
> 
> > -----Original Message-----
> > From: Jie Wang <jie1x.wang@intel.com>
> > Sent: Thursday, October 21, 2021 9:26 AM
> > Subject: [PATCH v7 1/3] ethdev: support L2TPv2 and PPP procotol
> >
> > Added flow pattern items and header formats of L2TPv2 and PPP.
> >
> > Signed-off-by: Wenjun Wu <wenjun1.wu@intel.com>
> > Signed-off-by: Jie Wang <jie1x.wang@intel.com>
> > ---
> >  doc/api/doxy-api-index.md              |   2 +
> >  doc/guides/nics/features/default.ini   |   2 +
> >  doc/guides/nics/features/iavf.ini      |   2 +
> >  doc/guides/prog_guide/rte_flow.rst     |  25 +++
> >  doc/guides/rel_notes/release_21_11.rst |   4 +
> >  lib/ethdev/rte_flow.c                  |   2 +
> >  lib/ethdev/rte_flow.h                  |  65 +++++++
> >  lib/net/meson.build                    |   2 +
> >  lib/net/rte_l2tpv2.h                   | 234 +++++++++++++++++++++++++
> >  lib/net/rte_ppp.h                      |  34 ++++
> >  10 files changed, 372 insertions(+)
> >  create mode 100644 lib/net/rte_l2tpv2.h  create mode 100644
> > lib/net/rte_ppp.h
> >
> > diff --git a/doc/api/doxy-api-index.md b/doc/api/doxy-api-index.md
> > index 1992107a03..42db196afe 100644
> > --- a/doc/api/doxy-api-index.md
> > +++ b/doc/api/doxy-api-index.md
> > @@ -121,6 +121,8 @@ The public API headers are grouped by topics:
> >    [VXLAN]              (@ref rte_vxlan.h),
> >    [Geneve]             (@ref rte_geneve.h),
> >    [eCPRI]              (@ref rte_ecpri.h)
> > +  [L2TPv2]             (@ref rte_l2tpv2.h)
> > +  [PPP]                (@ref rte_ppp.h)
> >
> >  - **QoS**:
> >    [metering]           (@ref rte_meter.h),
> > diff --git a/doc/guides/nics/features/default.ini
> > b/doc/guides/nics/features/default.ini
> > index 09914b1ad3..8e6a28c419 100644
> > --- a/doc/guides/nics/features/default.ini
> > +++ b/doc/guides/nics/features/default.ini
> > @@ -110,6 +110,7 @@ ipv4                 =
> >  ipv6                 =
> >  ipv6_ext             =
> >  ipv6_frag_ext        =
> > +l2tpv2               =
> >  l2tpv3oip            =
> >  mark                 =
> >  meta                 =
> > @@ -121,6 +122,7 @@ pfcp                 =
> >  phy_port             =
> >  port_id              =
> >  port_representor     =
> > +ppp                  =
> >  pppoed               =
> >  pppoes               =
> >  pppoe_proto_id       =
> > diff --git a/doc/guides/nics/features/iavf.ini
> > b/doc/guides/nics/features/iavf.ini
> > index d00ca934c3..a916275b88 100644
> > --- a/doc/guides/nics/features/iavf.ini
> > +++ b/doc/guides/nics/features/iavf.ini
> > @@ -50,8 +50,10 @@ icmp6                = Y
> >  ipv4                 = Y
> >  ipv6                 = Y
> >  ipv6_frag_ext        = Y
> > +l2tpv2               = Y
> >  l2tpv3oip            = Y
> >  pfcp                 = Y
> > +ppp                  = Y
> >  sctp                 = Y
> >  tcp                  = Y
> >  udp                  = Y
> > diff --git a/doc/guides/prog_guide/rte_flow.rst
> > b/doc/guides/prog_guide/rte_flow.rst
> > index aeba374182..a2169517c3 100644
> > --- a/doc/guides/prog_guide/rte_flow.rst
> > +++ b/doc/guides/prog_guide/rte_flow.rst
> > @@ -1573,6 +1573,31 @@ rte_flow_flex_item_create() routine.
> >    as padded with trailing zeroes up to full configured length, both for
> >    value and mask.
> >
> > +Item: ``L2TPV2``
> > +^^^^^^^^^^^^^^^^^^^
> > +
> > +Matches a L2TPv2 header.
> > +
> > +- ``flags_version``: flags(12b), version(4b).
> > +- ``length``: total length of the message.
> > +- ``tunnel_id``: identifier for the control connection.
> > +- ``session_id``: identifier for a session within a tunnel.
> > +- ``ns``: sequence number for this date or control message.
> > +- ``nr``: sequence number expected in the next control message to be
> received.
> > +- ``offset_size``: offset of payload data.
> > +- ``offset_padding``: offset padding, variable length.
> > +- Default ``mask`` matches flags_version only.
> > +
> > +Item: ``PPP``
> > +^^^^^^^^^^^^^^^^^^^
> > +
> > +Matches a PPP header.
> > +
> > +- ``addr``: PPP address.
> > +- ``ctrl``: PPP control.
> > +- ``proto_id``: PPP protocol identifier.
> > +- Default ``mask`` matches addr, ctrl, proto_id.
> > +
> >  Actions
> >  ~~~~~~~
> >
> > diff --git a/doc/guides/rel_notes/release_21_11.rst
> > b/doc/guides/rel_notes/release_21_11.rst
> > index 041383ee2a..283770131c 100644
> > --- a/doc/guides/rel_notes/release_21_11.rst
> > +++ b/doc/guides/rel_notes/release_21_11.rst
> > @@ -105,6 +105,10 @@ New Features
> >
> >    Added an ethdev API which can help users get device configuration.
> >
> > +* **Added L2TPv2 and PPP protocol support in rte_flow.**
> > +
> > +  Added flow pattern items and header formats of L2TPv2 and PPP protocol.
> > +
> >  * **Updated AF_XDP PMD.**
> >
> >    * Disabled secondary process support.
> > diff --git a/lib/ethdev/rte_flow.c b/lib/ethdev/rte_flow.c index
> > bcf0513b3c..d268784532 100644
> > --- a/lib/ethdev/rte_flow.c
> > +++ b/lib/ethdev/rte_flow.c
> > @@ -156,6 +156,8 @@ static const struct rte_flow_desc_data
> rte_flow_desc_item[] = {
> >  	MK_FLOW_ITEM(REPRESENTED_PORT, sizeof(struct
> rte_flow_item_ethdev)),
> >  	MK_FLOW_ITEM_FN(FLEX, sizeof(struct rte_flow_item_flex),
> >  			rte_flow_item_flex_conv),
> > +	MK_FLOW_ITEM(L2TPV2, sizeof(struct rte_flow_item_l2tpv2)),
> > +	MK_FLOW_ITEM(PPP, sizeof(struct rte_flow_item_ppp)),
> >  };
> >
> >  /** Generate flow_action[] entry. */
> > diff --git a/lib/ethdev/rte_flow.h b/lib/ethdev/rte_flow.h index
> > 64ed7f2618..300e99e16b 100644
> > --- a/lib/ethdev/rte_flow.h
> > +++ b/lib/ethdev/rte_flow.h
> > @@ -35,6 +35,8 @@
> >  #include <rte_mbuf_dyn.h>
> >  #include <rte_meter.h>
> >  #include <rte_gtp.h>
> > +#include <rte_l2tpv2.h>
> > +#include <rte_ppp.h>
> >
> >  #ifdef __cplusplus
> >  extern "C" {
> > @@ -644,6 +646,20 @@ enum rte_flow_item_type {
> >  	 * @see struct rte_flow_item_flex.
> >  	 */
> >  	RTE_FLOW_ITEM_TYPE_FLEX,
> > +
> > +	/**
> > +	 * Matches L2TPv2 Header.
> > +	 *
> > +	 * See struct rte_flow_item_l2tpv2.
> > +	 */
> > +	RTE_FLOW_ITEM_TYPE_L2TPV2,
> > +
> > +	/**
> > +	 * Matches PPP Header.
> > +	 *
> > +	 * See struct rte_flow_item_ppp.
> > +	 */
> > +	RTE_FLOW_ITEM_TYPE_PPP,
> >  };
> >
> >  /**
> > @@ -1900,6 +1916,55 @@ static const struct rte_flow_item_ethdev
> > rte_flow_item_ethdev_mask = {  };  #endif
> >
> > +/**
> > + * @warning
> > + * @b EXPERIMENTAL: this structure may change without prior notice
> > + * RTE_FLOW_ITEM_TYPE_L2TPV2
> > + *
> > + * Matches L2TPv2 Header
> > + */
> > +struct rte_flow_item_l2tpv2 {
> > +	struct rte_l2tpv2_combined_msg_hdr hdr; };
> > +
> > +/** Default mask for RTE_FLOW_ITEM_TYPE_L2TPV2. */ #ifndef
> > +__cplusplus static const struct rte_flow_item_l2tpv2
> > +rte_flow_item_l2tpv2_mask = {
> > +	/*
> > +	 * flags and version bit mask
> > +	 * 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0
> > +	 * T L x x S x O P x x x x V V V V
> > +	 */
> > +	.hdr = {
> > +		.common = {
> > +			.flags_version = RTE_BE16(0xcb0f),
> > +		},
> > +	},
> > +};
> > +#endif
> > +
> > +/**
> > + * @warning
> > + * @b EXPERIMENTAL: this structure may change without prior notice
> > + * RTE_FLOW_ITEM_TYPE_PPP
> > + *
> > + * Matches PPP Header
> > + */
> > +struct rte_flow_item_ppp {
> > +	struct rte_ppp_hdr hdr;
> > +};
> > +
> > +/** Default mask for RTE_FLOW_ITEM_TYPE_PPP. */ #ifndef __cplusplus
> > +static const struct rte_flow_item_ppp rte_flow_item_ppp_mask = {
> > +	.hdr = {
> > +		.addr = 0xff,
> > +		.ctrl = 0xff,
> > +		.proto_id = RTE_BE16(0xffff),
> > +	}
> > +};
> > +#endif
> > +
> >  /**
> >   * Matching pattern item definition.
> >   *
> > diff --git a/lib/net/meson.build b/lib/net/meson.build index
> > a4e395e9c5..e899846578 100644
> > --- a/lib/net/meson.build
> > +++ b/lib/net/meson.build
> > @@ -19,6 +19,8 @@ headers = files(
> >          'rte_higig.h',
> >          'rte_ecpri.h',
> >          'rte_geneve.h',
> > +        'rte_l2tpv2.h',
> > +        'rte_ppp.h',
> >  )
> >
> >  sources = files(
> > diff --git a/lib/net/rte_l2tpv2.h b/lib/net/rte_l2tpv2.h new file mode
> > 100644 index 0000000000..18ea759ff4
> > --- /dev/null
> > +++ b/lib/net/rte_l2tpv2.h
> > @@ -0,0 +1,234 @@
> > +/* SPDX-License-Identifier: BSD-3-Clause
> > + * Copyright 2021 Mellanox Technologies, Ltd  */
> > +
> > +#ifndef _RTE_L2TPV2_H_
> > +#define _RTE_L2TPV2_H_
> > +
> > +/**
> > + * @file
> > + *
> > + * L2TP header:
> > + *
> > + * `-0--------------------1----------------2-------------------3`
> > + *
> > + * `-0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1`
> > + *
> > + *
> > +`+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+`
> > + *
> > + * `|T|L|x|x|S|x|O|P|x|x|x|x|--Ver--|-----------Length
> > +(opt)--------|`
> > + *
> > + *
> > +`+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+`
> > + *
> > + * `|-----------Tunnel ID-----------|-----------Session
> > +ID----------|`
> > + *
> > + *
> > +`+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+`
> > + *
> > + * `|-----------Ns (opt)------------|-----------Nr
> > +(opt)------------|`
> > + *
> > + *
> > +`+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+`
> > + *
> > + * `|---------Offset Size (opt)-----|---------Offset pad... (opt)`
> > + *
> > + *
> > +`+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+`
> > + *
> > + * The Type (T) bit indicates the type of message. It is set to 0 for
> > +a data
> > + * message and 1 for a control message.
> > + *
> > + * If the Length (L) bit is 1, the Length field is present. This bit
> > +MUST be
> > + * set to 1 for control messages.
> > + *
> > + * The x bits are reserved for future extensions. All reserved bits
> > +MUST
> > + * be set to 0 on outgoing messages and ignored on incoming messages.
> > + *
> > + * If the Sequence (S) bit is set to 1 the Ns and Nr fields are present.
> > + * The S bit MUST be set to 1 for control messages.
> > + *
> > + * If the Offset (O) bit is 1, the Offset Size field is present. The
> > +O
> > + * bit MUST be set to 0 for control messages.
> > + *
> > + * If the Priority (P) bit is 1, this data message should receive
> > + * preferential treatment in its local queuing and transmission.
> > + * The P bit MUST be set to 0 for control messages.
> > + *
> > + * Ver MUST be 2, indicating the version of the L2TP data message header.
> > + *
> > + * The Length field indicates the total length of the message in octets.
> > + *
> > + * Tunnel ID indicates the identifier for the control connection.
> > + *
> > + * Session ID indicates the identifier for a session within a tunnel.
> > + *
> > + * Ns indicates the sequence number for this data or control message.
> > + *
> > + * Nr indicates the sequence number expected in the next control
> > +message
> > + * to be received.
> > + *
> > + * The Offset Size field, if present, specifies the number of octets
> > + * past the L2TP header at which the payload data is expected to start.
> > + * Actual data within the offset padding is undefined. If the offset
> > + * field is present, the L2TP header ends after the last octet of the
> > + * offset padding.
> > + */
> > +
> > +#include <stdint.h>
> > +#include <rte_byteorder.h>
> > +
> > +#ifdef __cplusplus
> > +extern "C" {
> > +#endif
> > +
> > +/**
> > + * L2TPv2 Common Header
> > + */
> > +RTE_STD_C11
> > +struct rte_l2tpv2_common_hdr {
> > +	union {
> > +		/** header flags and protocol version */
> > +		rte_be16_t flags_version;
> > +		struct {
> > +#if RTE_BYTE_ORDER == RTE_LITTLE_ENDIAN
> > +			rte_be16_t t:1;		/**< message Type */
> > +			rte_be16_t l:1;		/**< length option bit */
> > +			rte_be16_t res1:2;	/**< reserved */
> > +			rte_be16_t s:1;		/**< ns/nr option bit */
> > +			rte_be16_t res2:1;	/**< reserved */
> > +			rte_be16_t o:1;		/**< offset option bit */
> > +			rte_be16_t p:1;		/**< priority option bit */
> > +			rte_be16_t res3:4;	/**< reserved */
> > +			rte_be16_t ver:4;	/**< protocol version */
> > +#elif RTE_BYTE_ORDER == RTE_BIG_ENDIAN
> > +			rte_be16_t ver:4;	/**< protocol version */
> > +			rte_be16_t res3:4;	/**< reserved */
> > +			rte_be16_t p:1;		/**< priority option bit */
> > +			rte_be16_t o:1;		/**< offset option bit */
> > +			rte_be16_t res2:1;	/**< reserved */
> > +			rte_be16_t s:1;		/**< ns/nr option bit */
> > +			rte_be16_t res1:2;	/**< reserved */
> > +			rte_be16_t l:1;		/**< length option bit */
> > +			rte_be16_t t:1;		/**< message Type */
> > +#endif
> > +		};
> > +	};
> > +};
> > +
> > +/**
> > + * L2TPv2 message Header contains all options(length, ns, nr,
> > + * offset size, offset padding).
> > + */
> > +struct rte_l2tpv2_msg_with_all_options {
> > +	rte_be16_t length;		/**< length(16) */
> > +	rte_be16_t tunnel_id;		/**< tunnel ID(16) */
> > +	rte_be16_t session_id;		/**< session ID(16) */
> > +	rte_be16_t ns;			/**< Ns(16) */
> > +	rte_be16_t nr;			/**< Nr(16) */
> > +	rte_be16_t offset_size;		/**< offset size(16) */
> > +	uint8_t   *offset_padding;	/**< offset padding(variable length) */
> > +};
> > +
> > +/**
> > + * L2TPv2 message Header contains all options except length(ns, nr,
> > + * offset size, offset padding).
> > + */
> > +struct rte_l2tpv2_msg_without_length {
> > +	rte_be16_t tunnel_id;		/**< tunnel ID(16) */
> > +	rte_be16_t session_id;		/**< session ID(16) */
> > +	rte_be16_t ns;			/**< Ns(16) */
> > +	rte_be16_t nr;			/**< Nr(16) */
> > +	rte_be16_t offset_size;		/**< offset size(16) */
> > +	uint8_t   *offset_padding;	/**< offset padding(variable length) */
> > +};
> > +
> > +/**
> > + * L2TPv2 message Header contains all options except ns_nr(length,
> > + * offset size, offset padding).
> > + * Ns and Nr MUST be toghter.
> > + */
> > +struct rte_l2tpv2_msg_without_ns_nr {
> > +	rte_be16_t length;		/**< length(16) */
> > +	rte_be16_t tunnel_id;		/**< tunnel ID(16) */
> > +	rte_be16_t session_id;		/**< session ID(16) */
> > +	rte_be16_t offset_size;		/**< offset size(16) */
> > +	uint8_t   *offset_padding;	/**< offset padding(variable length) */
> > +};
> > +
> > +/**
> > + * L2TPv2 message Header contains all options except ns_nr(length, ns, nr).
> > + * offset size and offset padding MUST be toghter.
> > + */
> > +struct rte_l2tpv2_msg_without_offset {
> > +	rte_be16_t length;		/**< length(16) */
> > +	rte_be16_t tunnel_id;		/**< tunnel ID(16) */
> > +	rte_be16_t session_id;		/**< session ID(16) */
> > +	rte_be16_t ns;			/**< Ns(16) */
> > +	rte_be16_t nr;			/**< Nr(16) */
> > +};
> 
> Why not packed?
> 
> > +
> > +/**
> > + * L2TPv2 message Header contains options offset size and offset padding.
> > + */
> > +struct rte_l2tpv2_msg_with_offset {
> > +	rte_be16_t tunnel_id;		/**< tunnel ID(16) */
> > +	rte_be16_t session_id;		/**< session ID(16) */
> > +	rte_be16_t offset_size;		/**< offset size(16) */
> > +	uint8_t   *offset_padding;	/**< offset padding(variable length) */
> > +};
> > +
> > +/**
> > + * L2TPv2 message Header contains options ns and nr.
> > + */
> > +struct rte_l2tpv2_msg_with_ns_nr {
> > +	rte_be16_t tunnel_id;		/**< tunnel ID(16) */
> > +	rte_be16_t session_id;		/**< session ID(16) */
> > +	rte_be16_t ns;			/**< Ns(16) */
> > +	rte_be16_t nr;			/**< Nr(16) */
> > +};
> 
> Why not packed? Same for all structs.
> 
> 
Hi Ori,

Do you mean I should pack Ns/Nr into a structure as a field? And pack offset size/offset padding into another structure?

> > +
> > +/**
> > + * L2TPv2 message Header contains option length.
> > + */
> > +struct rte_l2tpv2_msg_with_length {
> > +	rte_be16_t length;		/**< length(16) */
> > +	rte_be16_t tunnel_id;		/**< tunnel ID(16) */
> > +	rte_be16_t session_id;		/**< session ID(16) */
> > +};
> > +
> > +/**
> > + * L2TPv2 message Header without all options.
> > + */
> > +struct rte_l2tpv2_msg_without_all_options {
> > +	rte_be16_t tunnel_id;		/**< tunnel ID(16) */
> > +	rte_be16_t session_id;		/**< session ID(16) */
> > +};
> > +
> > +/**
> > + * L2TPv2 Combined Message Header Format: Common Header + Options  */
> > +RTE_STD_C11
> > +struct rte_l2tpv2_combined_msg_hdr {
> > +	struct rte_l2tpv2_common_hdr common; /**< common header */
> > +	union {
> > +		/** header with all options */
> > +		struct rte_l2tpv2_msg_with_all_options type0;
> > +		/** header with all options except length */
> > +		struct rte_l2tpv2_msg_without_length type1;
> > +		/** header with all options except ns/nr */
> > +		struct rte_l2tpv2_msg_without_ns_nr type2;
> > +		/** header with all options except offset */
> > +		struct rte_l2tpv2_msg_without_offset type3;
> > +		/** header with offset options */
> > +		struct rte_l2tpv2_msg_with_offset type4;
> > +		/** header with ns/nr options */
> > +		struct rte_l2tpv2_msg_with_ns_nr type5;
> > +		/** header with length option */
> > +		struct rte_l2tpv2_msg_with_length type6;
> > +		/** header without all options */
> > +		struct rte_l2tpv2_msg_without_all_options type7;
> > +	};
> > +};
> > +
> > +#ifdef __cplusplus
> > +}
> > +#endif
> > +
> > +#endif /* _RTE_L2TPV2_H_ */
> > diff --git a/lib/net/rte_ppp.h b/lib/net/rte_ppp.h new file mode
> > 100644 index 0000000000..2a53cd969f
> > --- /dev/null
> > +++ b/lib/net/rte_ppp.h
> > @@ -0,0 +1,34 @@
> > +/* SPDX-License-Identifier: BSD-3-Clause
> > + * Copyright 2021 Mellanox Technologies, Ltd  */
> > +
> > +#ifndef _RTE_PPP_H_
> > +#define _RTE_PPP_H_
> > +
> > +/**
> > + * @file
> > + *
> > + * PPP headers definition.
> > + */
> > +
> > +#include <stdint.h>
> > +#include <rte_byteorder.h>
> > +
> > +#ifdef __cplusplus
> > +extern "C" {
> > +#endif
> > +
> > +/**
> > + * PPP Header
> > + */
> > +struct rte_ppp_hdr {
> > +	uint8_t addr; /**< PPP address(8) */
> > +	uint8_t ctrl; /**< PPP control(8) */
> > +	rte_be16_t proto_id; /**< PPP protocol identifier(16) */ }
> > +__rte_packed;
> > +
> > +#ifdef __cplusplus
> > +}
> > +#endif
> > +
> > +#endif /* _RTE_PPP_H_ */
> > --
> > 2.25.1
> 
> Best,
> Ori

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

* Re: [dpdk-dev] [PATCH v7 1/3] ethdev: support L2TPv2 and PPP procotol
  2021-10-21  7:50               ` Ori Kam
  2021-10-21  7:52                 ` Andrew Rybchenko
  2021-10-21  8:41                 ` Wang, Jie1X
@ 2021-10-21  9:26                 ` Ferruh Yigit
  2 siblings, 0 replies; 71+ messages in thread
From: Ferruh Yigit @ 2021-10-21  9:26 UTC (permalink / raw)
  To: Ori Kam, Jie Wang, dev, Olivier Matz
  Cc: NBU-Contact-Thomas Monjalon, andrew.rybchenko, xiaoyun.li,
	stevex.yang, jingjing.wu, beilei.xing, wenjun1.wu, qi.z.zhang

On 10/21/2021 8:50 AM, Ori Kam wrote:
> Hi Jie,
> 
>> -----Original Message-----
>> From: Jie Wang <jie1x.wang@intel.com>
>> Sent: Thursday, October 21, 2021 9:26 AM
>> Subject: [PATCH v7 1/3] ethdev: support L2TPv2 and PPP procotol
>>
>> Added flow pattern items and header formats of L2TPv2 and PPP.
>>
>> Signed-off-by: Wenjun Wu <wenjun1.wu@intel.com>
>> Signed-off-by: Jie Wang <jie1x.wang@intel.com>
>> ---
>>   doc/api/doxy-api-index.md              |   2 +
>>   doc/guides/nics/features/default.ini   |   2 +
>>   doc/guides/nics/features/iavf.ini      |   2 +
>>   doc/guides/prog_guide/rte_flow.rst     |  25 +++
>>   doc/guides/rel_notes/release_21_11.rst |   4 +
>>   lib/ethdev/rte_flow.c                  |   2 +
>>   lib/ethdev/rte_flow.h                  |  65 +++++++
>>   lib/net/meson.build                    |   2 +
>>   lib/net/rte_l2tpv2.h                   | 234 +++++++++++++++++++++++++
>>   lib/net/rte_ppp.h                      |  34 ++++
>>   10 files changed, 372 insertions(+)
>>   create mode 100644 lib/net/rte_l2tpv2.h
>>   create mode 100644 lib/net/rte_ppp.h
>>
>> diff --git a/doc/api/doxy-api-index.md b/doc/api/doxy-api-index.md
>> index 1992107a03..42db196afe 100644
>> --- a/doc/api/doxy-api-index.md
>> +++ b/doc/api/doxy-api-index.md
>> @@ -121,6 +121,8 @@ The public API headers are grouped by topics:
>>     [VXLAN]              (@ref rte_vxlan.h),
>>     [Geneve]             (@ref rte_geneve.h),
>>     [eCPRI]              (@ref rte_ecpri.h)
>> +  [L2TPv2]             (@ref rte_l2tpv2.h)
>> +  [PPP]                (@ref rte_ppp.h)
>>
>>   - **QoS**:
>>     [metering]           (@ref rte_meter.h),
>> diff --git a/doc/guides/nics/features/default.ini b/doc/guides/nics/features/default.ini
>> index 09914b1ad3..8e6a28c419 100644
>> --- a/doc/guides/nics/features/default.ini
>> +++ b/doc/guides/nics/features/default.ini
>> @@ -110,6 +110,7 @@ ipv4                 =
>>   ipv6                 =
>>   ipv6_ext             =
>>   ipv6_frag_ext        =
>> +l2tpv2               =
>>   l2tpv3oip            =
>>   mark                 =
>>   meta                 =
>> @@ -121,6 +122,7 @@ pfcp                 =
>>   phy_port             =
>>   port_id              =
>>   port_representor     =
>> +ppp                  =
>>   pppoed               =
>>   pppoes               =
>>   pppoe_proto_id       =
>> diff --git a/doc/guides/nics/features/iavf.ini b/doc/guides/nics/features/iavf.ini
>> index d00ca934c3..a916275b88 100644
>> --- a/doc/guides/nics/features/iavf.ini
>> +++ b/doc/guides/nics/features/iavf.ini
>> @@ -50,8 +50,10 @@ icmp6                = Y
>>   ipv4                 = Y
>>   ipv6                 = Y
>>   ipv6_frag_ext        = Y
>> +l2tpv2               = Y
>>   l2tpv3oip            = Y
>>   pfcp                 = Y
>> +ppp                  = Y
>>   sctp                 = Y
>>   tcp                  = Y
>>   udp                  = Y
>> diff --git a/doc/guides/prog_guide/rte_flow.rst b/doc/guides/prog_guide/rte_flow.rst
>> index aeba374182..a2169517c3 100644
>> --- a/doc/guides/prog_guide/rte_flow.rst
>> +++ b/doc/guides/prog_guide/rte_flow.rst
>> @@ -1573,6 +1573,31 @@ rte_flow_flex_item_create() routine.
>>     as padded with trailing zeroes up to full configured length, both for
>>     value and mask.
>>
>> +Item: ``L2TPV2``
>> +^^^^^^^^^^^^^^^^^^^
>> +
>> +Matches a L2TPv2 header.
>> +
>> +- ``flags_version``: flags(12b), version(4b).
>> +- ``length``: total length of the message.
>> +- ``tunnel_id``: identifier for the control connection.
>> +- ``session_id``: identifier for a session within a tunnel.
>> +- ``ns``: sequence number for this date or control message.
>> +- ``nr``: sequence number expected in the next control message to be received.
>> +- ``offset_size``: offset of payload data.
>> +- ``offset_padding``: offset padding, variable length.
>> +- Default ``mask`` matches flags_version only.
>> +
>> +Item: ``PPP``
>> +^^^^^^^^^^^^^^^^^^^
>> +
>> +Matches a PPP header.
>> +
>> +- ``addr``: PPP address.
>> +- ``ctrl``: PPP control.
>> +- ``proto_id``: PPP protocol identifier.
>> +- Default ``mask`` matches addr, ctrl, proto_id.
>> +
>>   Actions
>>   ~~~~~~~
>>
>> diff --git a/doc/guides/rel_notes/release_21_11.rst b/doc/guides/rel_notes/release_21_11.rst
>> index 041383ee2a..283770131c 100644
>> --- a/doc/guides/rel_notes/release_21_11.rst
>> +++ b/doc/guides/rel_notes/release_21_11.rst
>> @@ -105,6 +105,10 @@ New Features
>>
>>     Added an ethdev API which can help users get device configuration.
>>
>> +* **Added L2TPv2 and PPP protocol support in rte_flow.**
>> +
>> +  Added flow pattern items and header formats of L2TPv2 and PPP protocol.
>> +
>>   * **Updated AF_XDP PMD.**
>>
>>     * Disabled secondary process support.
>> diff --git a/lib/ethdev/rte_flow.c b/lib/ethdev/rte_flow.c
>> index bcf0513b3c..d268784532 100644
>> --- a/lib/ethdev/rte_flow.c
>> +++ b/lib/ethdev/rte_flow.c
>> @@ -156,6 +156,8 @@ static const struct rte_flow_desc_data rte_flow_desc_item[] = {
>>   	MK_FLOW_ITEM(REPRESENTED_PORT, sizeof(struct rte_flow_item_ethdev)),
>>   	MK_FLOW_ITEM_FN(FLEX, sizeof(struct rte_flow_item_flex),
>>   			rte_flow_item_flex_conv),
>> +	MK_FLOW_ITEM(L2TPV2, sizeof(struct rte_flow_item_l2tpv2)),
>> +	MK_FLOW_ITEM(PPP, sizeof(struct rte_flow_item_ppp)),
>>   };
>>
>>   /** Generate flow_action[] entry. */
>> diff --git a/lib/ethdev/rte_flow.h b/lib/ethdev/rte_flow.h
>> index 64ed7f2618..300e99e16b 100644
>> --- a/lib/ethdev/rte_flow.h
>> +++ b/lib/ethdev/rte_flow.h
>> @@ -35,6 +35,8 @@
>>   #include <rte_mbuf_dyn.h>
>>   #include <rte_meter.h>
>>   #include <rte_gtp.h>
>> +#include <rte_l2tpv2.h>
>> +#include <rte_ppp.h>
>>
>>   #ifdef __cplusplus
>>   extern "C" {
>> @@ -644,6 +646,20 @@ enum rte_flow_item_type {
>>   	 * @see struct rte_flow_item_flex.
>>   	 */
>>   	RTE_FLOW_ITEM_TYPE_FLEX,
>> +
>> +	/**
>> +	 * Matches L2TPv2 Header.
>> +	 *
>> +	 * See struct rte_flow_item_l2tpv2.
>> +	 */
>> +	RTE_FLOW_ITEM_TYPE_L2TPV2,
>> +
>> +	/**
>> +	 * Matches PPP Header.
>> +	 *
>> +	 * See struct rte_flow_item_ppp.
>> +	 */
>> +	RTE_FLOW_ITEM_TYPE_PPP,
>>   };
>>
>>   /**
>> @@ -1900,6 +1916,55 @@ static const struct rte_flow_item_ethdev rte_flow_item_ethdev_mask = {
>>   };
>>   #endif
>>
>> +/**
>> + * @warning
>> + * @b EXPERIMENTAL: this structure may change without prior notice
>> + * RTE_FLOW_ITEM_TYPE_L2TPV2
>> + *
>> + * Matches L2TPv2 Header
>> + */
>> +struct rte_flow_item_l2tpv2 {
>> +	struct rte_l2tpv2_combined_msg_hdr hdr;
>> +};
>> +
>> +/** Default mask for RTE_FLOW_ITEM_TYPE_L2TPV2. */
>> +#ifndef __cplusplus
>> +static const struct rte_flow_item_l2tpv2 rte_flow_item_l2tpv2_mask = {
>> +	/*
>> +	 * flags and version bit mask
>> +	 * 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0
>> +	 * T L x x S x O P x x x x V V V V
>> +	 */
>> +	.hdr = {
>> +		.common = {
>> +			.flags_version = RTE_BE16(0xcb0f),
>> +		},
>> +	},
>> +};
>> +#endif
>> +
>> +/**
>> + * @warning
>> + * @b EXPERIMENTAL: this structure may change without prior notice
>> + * RTE_FLOW_ITEM_TYPE_PPP
>> + *
>> + * Matches PPP Header
>> + */
>> +struct rte_flow_item_ppp {
>> +	struct rte_ppp_hdr hdr;
>> +};
>> +
>> +/** Default mask for RTE_FLOW_ITEM_TYPE_PPP. */
>> +#ifndef __cplusplus
>> +static const struct rte_flow_item_ppp rte_flow_item_ppp_mask = {
>> +	.hdr = {
>> +		.addr = 0xff,
>> +		.ctrl = 0xff,
>> +		.proto_id = RTE_BE16(0xffff),
>> +	}
>> +};
>> +#endif
>> +
>>   /**
>>    * Matching pattern item definition.
>>    *
>> diff --git a/lib/net/meson.build b/lib/net/meson.build
>> index a4e395e9c5..e899846578 100644
>> --- a/lib/net/meson.build
>> +++ b/lib/net/meson.build
>> @@ -19,6 +19,8 @@ headers = files(
>>           'rte_higig.h',
>>           'rte_ecpri.h',
>>           'rte_geneve.h',
>> +        'rte_l2tpv2.h',
>> +        'rte_ppp.h',
>>   )
>>
>>   sources = files(
>> diff --git a/lib/net/rte_l2tpv2.h b/lib/net/rte_l2tpv2.h
>> new file mode 100644
>> index 0000000000..18ea759ff4
>> --- /dev/null
>> +++ b/lib/net/rte_l2tpv2.h
>> @@ -0,0 +1,234 @@
>> +/* SPDX-License-Identifier: BSD-3-Clause
>> + * Copyright 2021 Mellanox Technologies, Ltd
>> + */
>> +
>> +#ifndef _RTE_L2TPV2_H_
>> +#define _RTE_L2TPV2_H_
>> +
>> +/**
>> + * @file
>> + *
>> + * L2TP header:
>> + *
>> + * `-0--------------------1----------------2-------------------3`
>> + *
>> + * `-0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1`
>> + *
>> + * `+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+`
>> + *
>> + * `|T|L|x|x|S|x|O|P|x|x|x|x|--Ver--|-----------Length (opt)--------|`
>> + *
>> + * `+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+`
>> + *
>> + * `|-----------Tunnel ID-----------|-----------Session ID----------|`
>> + *
>> + * `+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+`
>> + *
>> + * `|-----------Ns (opt)------------|-----------Nr (opt)------------|`
>> + *
>> + * `+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+`
>> + *
>> + * `|---------Offset Size (opt)-----|---------Offset pad... (opt)`
>> + *
>> + * `+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+`
>> + *
>> + * The Type (T) bit indicates the type of message. It is set to 0 for a data
>> + * message and 1 for a control message.
>> + *
>> + * If the Length (L) bit is 1, the Length field is present. This bit MUST be
>> + * set to 1 for control messages.
>> + *
>> + * The x bits are reserved for future extensions. All reserved bits MUST
>> + * be set to 0 on outgoing messages and ignored on incoming messages.
>> + *
>> + * If the Sequence (S) bit is set to 1 the Ns and Nr fields are present.
>> + * The S bit MUST be set to 1 for control messages.
>> + *
>> + * If the Offset (O) bit is 1, the Offset Size field is present. The O
>> + * bit MUST be set to 0 for control messages.
>> + *
>> + * If the Priority (P) bit is 1, this data message should receive
>> + * preferential treatment in its local queuing and transmission.
>> + * The P bit MUST be set to 0 for control messages.
>> + *
>> + * Ver MUST be 2, indicating the version of the L2TP data message header.
>> + *
>> + * The Length field indicates the total length of the message in octets.
>> + *
>> + * Tunnel ID indicates the identifier for the control connection.
>> + *
>> + * Session ID indicates the identifier for a session within a tunnel.
>> + *
>> + * Ns indicates the sequence number for this data or control message.
>> + *
>> + * Nr indicates the sequence number expected in the next control message
>> + * to be received.
>> + *
>> + * The Offset Size field, if present, specifies the number of octets
>> + * past the L2TP header at which the payload data is expected to start.
>> + * Actual data within the offset padding is undefined. If the offset
>> + * field is present, the L2TP header ends after the last octet of the
>> + * offset padding.
>> + */
>> +
>> +#include <stdint.h>
>> +#include <rte_byteorder.h>
>> +
>> +#ifdef __cplusplus
>> +extern "C" {
>> +#endif
>> +
>> +/**
>> + * L2TPv2 Common Header
>> + */
>> +RTE_STD_C11
>> +struct rte_l2tpv2_common_hdr {
>> +	union {
>> +		/** header flags and protocol version */
>> +		rte_be16_t flags_version;
>> +		struct {
>> +#if RTE_BYTE_ORDER == RTE_LITTLE_ENDIAN
>> +			rte_be16_t t:1;		/**< message Type */
>> +			rte_be16_t l:1;		/**< length option bit */
>> +			rte_be16_t res1:2;	/**< reserved */
>> +			rte_be16_t s:1;		/**< ns/nr option bit */
>> +			rte_be16_t res2:1;	/**< reserved */
>> +			rte_be16_t o:1;		/**< offset option bit */
>> +			rte_be16_t p:1;		/**< priority option bit */
>> +			rte_be16_t res3:4;	/**< reserved */
>> +			rte_be16_t ver:4;	/**< protocol version */
>> +#elif RTE_BYTE_ORDER == RTE_BIG_ENDIAN
>> +			rte_be16_t ver:4;	/**< protocol version */
>> +			rte_be16_t res3:4;	/**< reserved */
>> +			rte_be16_t p:1;		/**< priority option bit */
>> +			rte_be16_t o:1;		/**< offset option bit */
>> +			rte_be16_t res2:1;	/**< reserved */
>> +			rte_be16_t s:1;		/**< ns/nr option bit */
>> +			rte_be16_t res1:2;	/**< reserved */
>> +			rte_be16_t l:1;		/**< length option bit */
>> +			rte_be16_t t:1;		/**< message Type */
>> +#endif
>> +		};
>> +	};
>> +};
>> +
>> +/**
>> + * L2TPv2 message Header contains all options(length, ns, nr,
>> + * offset size, offset padding).
>> + */
>> +struct rte_l2tpv2_msg_with_all_options {
>> +	rte_be16_t length;		/**< length(16) */
>> +	rte_be16_t tunnel_id;		/**< tunnel ID(16) */
>> +	rte_be16_t session_id;		/**< session ID(16) */
>> +	rte_be16_t ns;			/**< Ns(16) */
>> +	rte_be16_t nr;			/**< Nr(16) */
>> +	rte_be16_t offset_size;		/**< offset size(16) */
>> +	uint8_t   *offset_padding;	/**< offset padding(variable length) */
>> +};
>> +
>> +/**
>> + * L2TPv2 message Header contains all options except length(ns, nr,
>> + * offset size, offset padding).
>> + */
>> +struct rte_l2tpv2_msg_without_length {
>> +	rte_be16_t tunnel_id;		/**< tunnel ID(16) */
>> +	rte_be16_t session_id;		/**< session ID(16) */
>> +	rte_be16_t ns;			/**< Ns(16) */
>> +	rte_be16_t nr;			/**< Nr(16) */
>> +	rte_be16_t offset_size;		/**< offset size(16) */
>> +	uint8_t   *offset_padding;	/**< offset padding(variable length) */
>> +};
>> +
>> +/**
>> + * L2TPv2 message Header contains all options except ns_nr(length,
>> + * offset size, offset padding).
>> + * Ns and Nr MUST be toghter.
>> + */
>> +struct rte_l2tpv2_msg_without_ns_nr {
>> +	rte_be16_t length;		/**< length(16) */
>> +	rte_be16_t tunnel_id;		/**< tunnel ID(16) */
>> +	rte_be16_t session_id;		/**< session ID(16) */
>> +	rte_be16_t offset_size;		/**< offset size(16) */
>> +	uint8_t   *offset_padding;	/**< offset padding(variable length) */
>> +};
>> +
>> +/**
>> + * L2TPv2 message Header contains all options except ns_nr(length, ns, nr).
>> + * offset size and offset padding MUST be toghter.
>> + */
>> +struct rte_l2tpv2_msg_without_offset {
>> +	rte_be16_t length;		/**< length(16) */
>> +	rte_be16_t tunnel_id;		/**< tunnel ID(16) */
>> +	rte_be16_t session_id;		/**< session ID(16) */
>> +	rte_be16_t ns;			/**< Ns(16) */
>> +	rte_be16_t nr;			/**< Nr(16) */
>> +};
> 
> Why not packed?
> 
>> +
>> +/**
>> + * L2TPv2 message Header contains options offset size and offset padding.
>> + */
>> +struct rte_l2tpv2_msg_with_offset {
>> +	rte_be16_t tunnel_id;		/**< tunnel ID(16) */
>> +	rte_be16_t session_id;		/**< session ID(16) */
>> +	rte_be16_t offset_size;		/**< offset size(16) */
>> +	uint8_t   *offset_padding;	/**< offset padding(variable length) */
>> +};
>> +
>> +/**
>> + * L2TPv2 message Header contains options ns and nr.
>> + */
>> +struct rte_l2tpv2_msg_with_ns_nr {
>> +	rte_be16_t tunnel_id;		/**< tunnel ID(16) */
>> +	rte_be16_t session_id;		/**< session ID(16) */
>> +	rte_be16_t ns;			/**< Ns(16) */
>> +	rte_be16_t nr;			/**< Nr(16) */
>> +};
> 
> Why not packed? Same for all structs.
> 

There is not gap in this struct, should we still pack it?
What it the expectation on packing the protocol structs? Have '__rte_packed' always?


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

* Re: [dpdk-dev] [PATCH v7 1/3] ethdev: support L2TPv2 and PPP procotol
  2021-10-21  6:26             ` [dpdk-dev] [PATCH v7 1/3] ethdev: support L2TPv2 and PPP procotol Jie Wang
  2021-10-21  7:50               ` Ori Kam
@ 2021-10-21  9:29               ` Ferruh Yigit
  1 sibling, 0 replies; 71+ messages in thread
From: Ferruh Yigit @ 2021-10-21  9:29 UTC (permalink / raw)
  To: Jie Wang, dev
  Cc: orika, thomas, andrew.rybchenko, xiaoyun.li, stevex.yang,
	jingjing.wu, beilei.xing, wenjun1.wu, qi.z.zhang

On 10/21/2021 7:26 AM, Jie Wang wrote:
> diff --git a/lib/net/rte_l2tpv2.h b/lib/net/rte_l2tpv2.h
> new file mode 100644
> index 0000000000..18ea759ff4
> --- /dev/null
> +++ b/lib/net/rte_l2tpv2.h
> @@ -0,0 +1,234 @@
> +/* SPDX-License-Identifier: BSD-3-Clause
> + * Copyright 2021 Mellanox Technologies, Ltd
> + */
> +

Please add Intel as copyright owner to new files, same for all:
Copyright(c) 2021 Intel Corporation.

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

* [dpdk-dev] [PATCH v8 0/3] support PPPoL2TPv2oUDP RSS Hash
  2021-10-21  6:26           ` [dpdk-dev] [PATCH v7 0/3] support PPPoL2TPv2oUDP RSS Hash Jie Wang
                               ` (2 preceding siblings ...)
  2021-10-21  6:26             ` [dpdk-dev] [PATCH v7 3/3] app/testpmd: support L2TPv2 and PPP protocol pattern Jie Wang
@ 2021-10-21 10:05             ` Jie Wang
  2021-10-21 10:05               ` [dpdk-dev] [PATCH v8 1/3] ethdev: support L2TPv2 and PPP procotol Jie Wang
                                 ` (3 more replies)
  3 siblings, 4 replies; 71+ messages in thread
From: Jie Wang @ 2021-10-21 10:05 UTC (permalink / raw)
  To: dev
  Cc: orika, ferruh.yigit, thomas, andrew.rybchenko, xiaoyun.li,
	stevex.yang, jingjing.wu, beilei.xing, wenjun1.wu, qi.z.zhang,
	Jie Wang

Support IAVF PPPoL2TPv2oUDP RSS Hash. Required to distribute packets
based on inner IP src+dest address and TCP/UDP src+dest port.

---
v8:
 * added '__rte_packed' in new protocol header.
 * update the comment in new protocol header file.
V7:
 * update ini file.
 * modify irregular spelling.
v6:
 * update release notes.
 * update lib/net/meson.build.
 * update testpmd_funcs.rst.
 * update doxygen comments in header files.
 * update doc/api/doxy-api-index.md.
v5: update release notes.
v4:
 * update commit log.
 * redefine PPP protocol header.
 * delete l2tpv2_encap.
v3:
 * add testpmd match PPP and L2TPv2 protocol header fields value.
 * add the code of l2tpv2_encap.
 * update the title of ethdev patch and adjust the position of
   the added code.
v2:
 * update the rte_flow.rst and release notes.
 * update l2tpv2 header format.

Jie Wang (3):
  ethdev: support L2TPv2 and PPP procotol
  net/iavf: support PPPoL2TPv2oUDP RSS Hash
  app/testpmd: support L2TPv2 and PPP protocol pattern

 app/test-pmd/cmdline_flow.c                 | 251 ++++++++++++++++++++
 doc/api/doxy-api-index.md                   |   2 +
 doc/guides/nics/features/default.ini        |   2 +
 doc/guides/nics/features/iavf.ini           |   2 +
 doc/guides/prog_guide/rte_flow.rst          |  25 ++
 doc/guides/rel_notes/release_21_11.rst      |   5 +
 doc/guides/testpmd_app_ug/testpmd_funcs.rst |  28 +++
 drivers/net/iavf/iavf_generic_flow.c        | 131 ++++++++++
 drivers/net/iavf/iavf_generic_flow.h        |  15 ++
 drivers/net/iavf/iavf_hash.c                | 108 ++++++++-
 lib/ethdev/rte_flow.c                       |   2 +
 lib/ethdev/rte_flow.h                       |  65 +++++
 lib/net/meson.build                         |   2 +
 lib/net/rte_l2tpv2.h                        | 234 ++++++++++++++++++
 lib/net/rte_ppp.h                           |  34 +++
 15 files changed, 904 insertions(+), 2 deletions(-)
 create mode 100644 lib/net/rte_l2tpv2.h
 create mode 100644 lib/net/rte_ppp.h

-- 
2.25.1


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

* [dpdk-dev] [PATCH v8 1/3] ethdev: support L2TPv2 and PPP procotol
  2021-10-21 10:05             ` [dpdk-dev] [PATCH v8 0/3] support PPPoL2TPv2oUDP RSS Hash Jie Wang
@ 2021-10-21 10:05               ` Jie Wang
  2021-10-21 10:13                 ` Andrew Rybchenko
  2021-10-21 10:05               ` [dpdk-dev] [PATCH v8 2/3] net/iavf: support PPPoL2TPv2oUDP RSS Hash Jie Wang
                                 ` (2 subsequent siblings)
  3 siblings, 1 reply; 71+ messages in thread
From: Jie Wang @ 2021-10-21 10:05 UTC (permalink / raw)
  To: dev
  Cc: orika, ferruh.yigit, thomas, andrew.rybchenko, xiaoyun.li,
	stevex.yang, jingjing.wu, beilei.xing, wenjun1.wu, qi.z.zhang,
	Jie Wang

Added flow pattern items and header formats of L2TPv2 and PPP.

Acked-by: Ori Kam <orika@nvidia.com>
Signed-off-by: Wenjun Wu <wenjun1.wu@intel.com>
Signed-off-by: Jie Wang <jie1x.wang@intel.com>
---
 doc/api/doxy-api-index.md              |   2 +
 doc/guides/nics/features/default.ini   |   2 +
 doc/guides/prog_guide/rte_flow.rst     |  25 +++
 doc/guides/rel_notes/release_21_11.rst |   4 +
 lib/ethdev/rte_flow.c                  |   2 +
 lib/ethdev/rte_flow.h                  |  65 +++++++
 lib/net/meson.build                    |   2 +
 lib/net/rte_l2tpv2.h                   | 234 +++++++++++++++++++++++++
 lib/net/rte_ppp.h                      |  34 ++++
 9 files changed, 370 insertions(+)
 create mode 100644 lib/net/rte_l2tpv2.h
 create mode 100644 lib/net/rte_ppp.h

diff --git a/doc/api/doxy-api-index.md b/doc/api/doxy-api-index.md
index 1992107a03..42db196afe 100644
--- a/doc/api/doxy-api-index.md
+++ b/doc/api/doxy-api-index.md
@@ -121,6 +121,8 @@ The public API headers are grouped by topics:
   [VXLAN]              (@ref rte_vxlan.h),
   [Geneve]             (@ref rte_geneve.h),
   [eCPRI]              (@ref rte_ecpri.h)
+  [L2TPv2]             (@ref rte_l2tpv2.h)
+  [PPP]                (@ref rte_ppp.h)
 
 - **QoS**:
   [metering]           (@ref rte_meter.h),
diff --git a/doc/guides/nics/features/default.ini b/doc/guides/nics/features/default.ini
index 09914b1ad3..8e6a28c419 100644
--- a/doc/guides/nics/features/default.ini
+++ b/doc/guides/nics/features/default.ini
@@ -110,6 +110,7 @@ ipv4                 =
 ipv6                 =
 ipv6_ext             =
 ipv6_frag_ext        =
+l2tpv2               =
 l2tpv3oip            =
 mark                 =
 meta                 =
@@ -121,6 +122,7 @@ pfcp                 =
 phy_port             =
 port_id              =
 port_representor     =
+ppp                  =
 pppoed               =
 pppoes               =
 pppoe_proto_id       =
diff --git a/doc/guides/prog_guide/rte_flow.rst b/doc/guides/prog_guide/rte_flow.rst
index aeba374182..a2169517c3 100644
--- a/doc/guides/prog_guide/rte_flow.rst
+++ b/doc/guides/prog_guide/rte_flow.rst
@@ -1573,6 +1573,31 @@ rte_flow_flex_item_create() routine.
   as padded with trailing zeroes up to full configured length, both for
   value and mask.
 
+Item: ``L2TPV2``
+^^^^^^^^^^^^^^^^^^^
+
+Matches a L2TPv2 header.
+
+- ``flags_version``: flags(12b), version(4b).
+- ``length``: total length of the message.
+- ``tunnel_id``: identifier for the control connection.
+- ``session_id``: identifier for a session within a tunnel.
+- ``ns``: sequence number for this date or control message.
+- ``nr``: sequence number expected in the next control message to be received.
+- ``offset_size``: offset of payload data.
+- ``offset_padding``: offset padding, variable length.
+- Default ``mask`` matches flags_version only.
+
+Item: ``PPP``
+^^^^^^^^^^^^^^^^^^^
+
+Matches a PPP header.
+
+- ``addr``: PPP address.
+- ``ctrl``: PPP control.
+- ``proto_id``: PPP protocol identifier.
+- Default ``mask`` matches addr, ctrl, proto_id.
+
 Actions
 ~~~~~~~
 
diff --git a/doc/guides/rel_notes/release_21_11.rst b/doc/guides/rel_notes/release_21_11.rst
index 041383ee2a..283770131c 100644
--- a/doc/guides/rel_notes/release_21_11.rst
+++ b/doc/guides/rel_notes/release_21_11.rst
@@ -105,6 +105,10 @@ New Features
 
   Added an ethdev API which can help users get device configuration.
 
+* **Added L2TPv2 and PPP protocol support in rte_flow.**
+
+  Added flow pattern items and header formats of L2TPv2 and PPP protocol.
+
 * **Updated AF_XDP PMD.**
 
   * Disabled secondary process support.
diff --git a/lib/ethdev/rte_flow.c b/lib/ethdev/rte_flow.c
index bcf0513b3c..d268784532 100644
--- a/lib/ethdev/rte_flow.c
+++ b/lib/ethdev/rte_flow.c
@@ -156,6 +156,8 @@ static const struct rte_flow_desc_data rte_flow_desc_item[] = {
 	MK_FLOW_ITEM(REPRESENTED_PORT, sizeof(struct rte_flow_item_ethdev)),
 	MK_FLOW_ITEM_FN(FLEX, sizeof(struct rte_flow_item_flex),
 			rte_flow_item_flex_conv),
+	MK_FLOW_ITEM(L2TPV2, sizeof(struct rte_flow_item_l2tpv2)),
+	MK_FLOW_ITEM(PPP, sizeof(struct rte_flow_item_ppp)),
 };
 
 /** Generate flow_action[] entry. */
diff --git a/lib/ethdev/rte_flow.h b/lib/ethdev/rte_flow.h
index 64ed7f2618..300e99e16b 100644
--- a/lib/ethdev/rte_flow.h
+++ b/lib/ethdev/rte_flow.h
@@ -35,6 +35,8 @@
 #include <rte_mbuf_dyn.h>
 #include <rte_meter.h>
 #include <rte_gtp.h>
+#include <rte_l2tpv2.h>
+#include <rte_ppp.h>
 
 #ifdef __cplusplus
 extern "C" {
@@ -644,6 +646,20 @@ enum rte_flow_item_type {
 	 * @see struct rte_flow_item_flex.
 	 */
 	RTE_FLOW_ITEM_TYPE_FLEX,
+
+	/**
+	 * Matches L2TPv2 Header.
+	 *
+	 * See struct rte_flow_item_l2tpv2.
+	 */
+	RTE_FLOW_ITEM_TYPE_L2TPV2,
+
+	/**
+	 * Matches PPP Header.
+	 *
+	 * See struct rte_flow_item_ppp.
+	 */
+	RTE_FLOW_ITEM_TYPE_PPP,
 };
 
 /**
@@ -1900,6 +1916,55 @@ static const struct rte_flow_item_ethdev rte_flow_item_ethdev_mask = {
 };
 #endif
 
+/**
+ * @warning
+ * @b EXPERIMENTAL: this structure may change without prior notice
+ * RTE_FLOW_ITEM_TYPE_L2TPV2
+ *
+ * Matches L2TPv2 Header
+ */
+struct rte_flow_item_l2tpv2 {
+	struct rte_l2tpv2_combined_msg_hdr hdr;
+};
+
+/** Default mask for RTE_FLOW_ITEM_TYPE_L2TPV2. */
+#ifndef __cplusplus
+static const struct rte_flow_item_l2tpv2 rte_flow_item_l2tpv2_mask = {
+	/*
+	 * flags and version bit mask
+	 * 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0
+	 * T L x x S x O P x x x x V V V V
+	 */
+	.hdr = {
+		.common = {
+			.flags_version = RTE_BE16(0xcb0f),
+		},
+	},
+};
+#endif
+
+/**
+ * @warning
+ * @b EXPERIMENTAL: this structure may change without prior notice
+ * RTE_FLOW_ITEM_TYPE_PPP
+ *
+ * Matches PPP Header
+ */
+struct rte_flow_item_ppp {
+	struct rte_ppp_hdr hdr;
+};
+
+/** Default mask for RTE_FLOW_ITEM_TYPE_PPP. */
+#ifndef __cplusplus
+static const struct rte_flow_item_ppp rte_flow_item_ppp_mask = {
+	.hdr = {
+		.addr = 0xff,
+		.ctrl = 0xff,
+		.proto_id = RTE_BE16(0xffff),
+	}
+};
+#endif
+
 /**
  * Matching pattern item definition.
  *
diff --git a/lib/net/meson.build b/lib/net/meson.build
index a4e395e9c5..e899846578 100644
--- a/lib/net/meson.build
+++ b/lib/net/meson.build
@@ -19,6 +19,8 @@ headers = files(
         'rte_higig.h',
         'rte_ecpri.h',
         'rte_geneve.h',
+        'rte_l2tpv2.h',
+        'rte_ppp.h',
 )
 
 sources = files(
diff --git a/lib/net/rte_l2tpv2.h b/lib/net/rte_l2tpv2.h
new file mode 100644
index 0000000000..54a617f10d
--- /dev/null
+++ b/lib/net/rte_l2tpv2.h
@@ -0,0 +1,234 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2021 Intel Corporation.
+ */
+
+#ifndef _RTE_L2TPV2_H_
+#define _RTE_L2TPV2_H_
+
+/**
+ * @file
+ *
+ * L2TP header:
+ *
+ * `-0--------------------1----------------2-------------------3`
+ *
+ * `-0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1`
+ *
+ * `+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+`
+ *
+ * `|T|L|x|x|S|x|O|P|x|x|x|x|--Ver--|-----------Length (opt)--------|`
+ *
+ * `+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+`
+ *
+ * `|-----------Tunnel ID-----------|-----------Session ID----------|`
+ *
+ * `+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+`
+ *
+ * `|-----------Ns (opt)------------|-----------Nr (opt)------------|`
+ *
+ * `+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+`
+ *
+ * `|---------Offset Size (opt)-----|---------Offset pad... (opt)`
+ *
+ * `+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+`
+ *
+ * The Type (T) bit indicates the type of message. It is set to 0 for a data
+ * message and 1 for a control message.
+ *
+ * If the Length (L) bit is 1, the Length field is present. This bit MUST be
+ * set to 1 for control messages.
+ *
+ * The x bits are reserved for future extensions. All reserved bits MUST
+ * be set to 0 on outgoing messages and ignored on incoming messages.
+ *
+ * If the Sequence (S) bit is set to 1 the Ns and Nr fields are present.
+ * The S bit MUST be set to 1 for control messages.
+ *
+ * If the Offset (O) bit is 1, the Offset Size field is present. The O
+ * bit MUST be set to 0 for control messages.
+ *
+ * If the Priority (P) bit is 1, this data message should receive
+ * preferential treatment in its local queuing and transmission.
+ * The P bit MUST be set to 0 for control messages.
+ *
+ * Ver MUST be 2, indicating the version of the L2TP data message header.
+ *
+ * The Length field indicates the total length of the message in octets.
+ *
+ * Tunnel ID indicates the identifier for the control connection.
+ *
+ * Session ID indicates the identifier for a session within a tunnel.
+ *
+ * Ns indicates the sequence number for this data or control message.
+ *
+ * Nr indicates the sequence number expected in the next control message
+ * to be received.
+ *
+ * The Offset Size field, if present, specifies the number of octets
+ * past the L2TP header at which the payload data is expected to start.
+ * Actual data within the offset padding is undefined. If the offset
+ * field is present, the L2TP header ends after the last octet of the
+ * offset padding.
+ */
+
+#include <stdint.h>
+#include <rte_byteorder.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * L2TPv2 Common Header
+ */
+RTE_STD_C11
+struct rte_l2tpv2_common_hdr {
+	union {
+		/** header flags and protocol version */
+		rte_be16_t flags_version;
+		struct {
+#if RTE_BYTE_ORDER == RTE_LITTLE_ENDIAN
+			rte_be16_t t:1;		/**< message Type */
+			rte_be16_t l:1;		/**< length option bit */
+			rte_be16_t res1:2;	/**< reserved */
+			rte_be16_t s:1;		/**< ns/nr option bit */
+			rte_be16_t res2:1;	/**< reserved */
+			rte_be16_t o:1;		/**< offset option bit */
+			rte_be16_t p:1;		/**< priority option bit */
+			rte_be16_t res3:4;	/**< reserved */
+			rte_be16_t ver:4;	/**< protocol version */
+#elif RTE_BYTE_ORDER == RTE_BIG_ENDIAN
+			rte_be16_t ver:4;	/**< protocol version */
+			rte_be16_t res3:4;	/**< reserved */
+			rte_be16_t p:1;		/**< priority option bit */
+			rte_be16_t o:1;		/**< offset option bit */
+			rte_be16_t res2:1;	/**< reserved */
+			rte_be16_t s:1;		/**< ns/nr option bit */
+			rte_be16_t res1:2;	/**< reserved */
+			rte_be16_t l:1;		/**< length option bit */
+			rte_be16_t t:1;		/**< message Type */
+#endif
+		};
+	};
+};
+
+/**
+ * L2TPv2 message Header contains all options(length, ns, nr,
+ * offset size, offset padding).
+ */
+struct rte_l2tpv2_msg_with_all_options {
+	rte_be16_t length;		/**< length(16) */
+	rte_be16_t tunnel_id;		/**< tunnel ID(16) */
+	rte_be16_t session_id;		/**< session ID(16) */
+	rte_be16_t ns;			/**< Ns(16) */
+	rte_be16_t nr;			/**< Nr(16) */
+	rte_be16_t offset_size;		/**< offset size(16) */
+	uint8_t   *offset_padding;	/**< offset padding(variable length) */
+} __rte_packed;
+
+/**
+ * L2TPv2 message Header contains all options except length(ns, nr,
+ * offset size, offset padding).
+ */
+struct rte_l2tpv2_msg_without_length {
+	rte_be16_t tunnel_id;		/**< tunnel ID(16) */
+	rte_be16_t session_id;		/**< session ID(16) */
+	rte_be16_t ns;			/**< Ns(16) */
+	rte_be16_t nr;			/**< Nr(16) */
+	rte_be16_t offset_size;		/**< offset size(16) */
+	uint8_t   *offset_padding;	/**< offset padding(variable length) */
+} __rte_packed;
+
+/**
+ * L2TPv2 message Header contains all options except ns_nr(length,
+ * offset size, offset padding).
+ * Ns and Nr MUST be toghter.
+ */
+struct rte_l2tpv2_msg_without_ns_nr {
+	rte_be16_t length;		/**< length(16) */
+	rte_be16_t tunnel_id;		/**< tunnel ID(16) */
+	rte_be16_t session_id;		/**< session ID(16) */
+	rte_be16_t offset_size;		/**< offset size(16) */
+	uint8_t   *offset_padding;	/**< offset padding(variable length) */
+};
+
+/**
+ * L2TPv2 message Header contains all options except ns_nr(length, ns, nr).
+ * offset size and offset padding MUST be toghter.
+ */
+struct rte_l2tpv2_msg_without_offset {
+	rte_be16_t length;		/**< length(16) */
+	rte_be16_t tunnel_id;		/**< tunnel ID(16) */
+	rte_be16_t session_id;		/**< session ID(16) */
+	rte_be16_t ns;			/**< Ns(16) */
+	rte_be16_t nr;			/**< Nr(16) */
+};
+
+/**
+ * L2TPv2 message Header contains options offset size and offset padding.
+ */
+struct rte_l2tpv2_msg_with_offset {
+	rte_be16_t tunnel_id;		/**< tunnel ID(16) */
+	rte_be16_t session_id;		/**< session ID(16) */
+	rte_be16_t offset_size;		/**< offset size(16) */
+	uint8_t   *offset_padding;	/**< offset padding(variable length) */
+} __rte_packed;
+
+/**
+ * L2TPv2 message Header contains options ns and nr.
+ */
+struct rte_l2tpv2_msg_with_ns_nr {
+	rte_be16_t tunnel_id;		/**< tunnel ID(16) */
+	rte_be16_t session_id;		/**< session ID(16) */
+	rte_be16_t ns;			/**< Ns(16) */
+	rte_be16_t nr;			/**< Nr(16) */
+} __rte_packed;
+
+/**
+ * L2TPv2 message Header contains option length.
+ */
+struct rte_l2tpv2_msg_with_length {
+	rte_be16_t length;		/**< length(16) */
+	rte_be16_t tunnel_id;		/**< tunnel ID(16) */
+	rte_be16_t session_id;		/**< session ID(16) */
+} __rte_packed;
+
+/**
+ * L2TPv2 message Header without all options.
+ */
+struct rte_l2tpv2_msg_without_all_options {
+	rte_be16_t tunnel_id;		/**< tunnel ID(16) */
+	rte_be16_t session_id;		/**< session ID(16) */
+} __rte_packed;
+
+/**
+ * L2TPv2 Combined Message Header Format: Common Header + Options
+ */
+RTE_STD_C11
+struct rte_l2tpv2_combined_msg_hdr {
+	struct rte_l2tpv2_common_hdr common; /**< common header */
+	union {
+		/** header with all options */
+		struct rte_l2tpv2_msg_with_all_options type0;
+		/** header with all options except length */
+		struct rte_l2tpv2_msg_without_length type1;
+		/** header with all options except ns/nr */
+		struct rte_l2tpv2_msg_without_ns_nr type2;
+		/** header with all options except offset */
+		struct rte_l2tpv2_msg_without_offset type3;
+		/** header with offset options */
+		struct rte_l2tpv2_msg_with_offset type4;
+		/** header with ns/nr options */
+		struct rte_l2tpv2_msg_with_ns_nr type5;
+		/** header with length option */
+		struct rte_l2tpv2_msg_with_length type6;
+		/** header without all options */
+		struct rte_l2tpv2_msg_without_all_options type7;
+	};
+} __rte_packed;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RTE_L2TPV2_H_ */
diff --git a/lib/net/rte_ppp.h b/lib/net/rte_ppp.h
new file mode 100644
index 0000000000..7b86ac4363
--- /dev/null
+++ b/lib/net/rte_ppp.h
@@ -0,0 +1,34 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2021 Intel Corporation.
+ */
+
+#ifndef _RTE_PPP_H_
+#define _RTE_PPP_H_
+
+/**
+ * @file
+ *
+ * PPP headers definition.
+ */
+
+#include <stdint.h>
+#include <rte_byteorder.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * PPP Header
+ */
+struct rte_ppp_hdr {
+	uint8_t addr; /**< PPP address(8) */
+	uint8_t ctrl; /**< PPP control(8) */
+	rte_be16_t proto_id; /**< PPP protocol identifier(16) */
+} __rte_packed;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RTE_PPP_H_ */
-- 
2.25.1


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

* [dpdk-dev] [PATCH v8 2/3] net/iavf: support PPPoL2TPv2oUDP RSS Hash
  2021-10-21 10:05             ` [dpdk-dev] [PATCH v8 0/3] support PPPoL2TPv2oUDP RSS Hash Jie Wang
  2021-10-21 10:05               ` [dpdk-dev] [PATCH v8 1/3] ethdev: support L2TPv2 and PPP procotol Jie Wang
@ 2021-10-21 10:05               ` Jie Wang
  2021-10-21 10:05               ` [dpdk-dev] [PATCH v8 3/3] app/testpmd: support L2TPv2 and PPP protocol pattern Jie Wang
  2021-10-21 10:49               ` [dpdk-dev] [PATCH v9 0/3] support PPPoL2TPv2oUDP RSS Hash Jie Wang
  3 siblings, 0 replies; 71+ messages in thread
From: Jie Wang @ 2021-10-21 10:05 UTC (permalink / raw)
  To: dev
  Cc: orika, ferruh.yigit, thomas, andrew.rybchenko, xiaoyun.li,
	stevex.yang, jingjing.wu, beilei.xing, wenjun1.wu, qi.z.zhang,
	Jie Wang

Add support for PPP over L2TPv2 over UDP protocol RSS Hash based
on inner IP src/dst address and TCP/UDP src/dst port.

Patterns are listed below:
eth/ipv4(6)/udp/l2tpv2/ppp/ipv4(6)
eth/ipv4(6)/udp/l2tpv2/ppp/ipv4(6)/udp
eth/ipv4(6)/udp/l2tpv2/ppp/ipv4(6)/tcp

Acked-by: Beilei Xing <beilei.xing@intel.com>
Signed-off-by: Wenjun Wu <wenjun1.wu@intel.com>
Signed-off-by: Jie Wang <jie1x.wang@intel.com>
---
 doc/guides/nics/features/iavf.ini      |   2 +
 doc/guides/rel_notes/release_21_11.rst |   1 +
 drivers/net/iavf/iavf_generic_flow.c   | 131 +++++++++++++++++++++++++
 drivers/net/iavf/iavf_generic_flow.h   |  15 +++
 drivers/net/iavf/iavf_hash.c           | 108 +++++++++++++++++++-
 5 files changed, 255 insertions(+), 2 deletions(-)

diff --git a/doc/guides/nics/features/iavf.ini b/doc/guides/nics/features/iavf.ini
index d00ca934c3..a916275b88 100644
--- a/doc/guides/nics/features/iavf.ini
+++ b/doc/guides/nics/features/iavf.ini
@@ -50,8 +50,10 @@ icmp6                = Y
 ipv4                 = Y
 ipv6                 = Y
 ipv6_frag_ext        = Y
+l2tpv2               = Y
 l2tpv3oip            = Y
 pfcp                 = Y
+ppp                  = Y
 sctp                 = Y
 tcp                  = Y
 udp                  = Y
diff --git a/doc/guides/rel_notes/release_21_11.rst b/doc/guides/rel_notes/release_21_11.rst
index 283770131c..bd0eacc0c5 100644
--- a/doc/guides/rel_notes/release_21_11.rst
+++ b/doc/guides/rel_notes/release_21_11.rst
@@ -132,6 +132,7 @@ New Features
 
   * Added Intel iavf support on Windows.
   * Added IPv4 and L4 (TCP/UDP/SCTP) checksum hash support in RSS flow.
+  * Added PPPoL2TPv2oUDP RSS hash based on inner IP address and TCP/UDP port.
 
 * **Updated Intel ice driver.**
 
diff --git a/drivers/net/iavf/iavf_generic_flow.c b/drivers/net/iavf/iavf_generic_flow.c
index b86d99e57d..364904fa02 100644
--- a/drivers/net/iavf/iavf_generic_flow.c
+++ b/drivers/net/iavf/iavf_generic_flow.c
@@ -1611,6 +1611,137 @@ enum rte_flow_item_type iavf_pattern_eth_ipv6_gre_ipv6_udp[] = {
 	RTE_FLOW_ITEM_TYPE_END,
 };
 
+/* PPPoL2TPv2oUDP */
+enum rte_flow_item_type iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv4[] = {
+	RTE_FLOW_ITEM_TYPE_ETH,
+	RTE_FLOW_ITEM_TYPE_IPV4,
+	RTE_FLOW_ITEM_TYPE_UDP,
+	RTE_FLOW_ITEM_TYPE_L2TPV2,
+	RTE_FLOW_ITEM_TYPE_PPP,
+	RTE_FLOW_ITEM_TYPE_IPV4,
+	RTE_FLOW_ITEM_TYPE_END,
+};
+
+enum rte_flow_item_type iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv6[] = {
+	RTE_FLOW_ITEM_TYPE_ETH,
+	RTE_FLOW_ITEM_TYPE_IPV4,
+	RTE_FLOW_ITEM_TYPE_UDP,
+	RTE_FLOW_ITEM_TYPE_L2TPV2,
+	RTE_FLOW_ITEM_TYPE_PPP,
+	RTE_FLOW_ITEM_TYPE_IPV6,
+	RTE_FLOW_ITEM_TYPE_END,
+};
+
+enum rte_flow_item_type iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv4_udp[] = {
+	RTE_FLOW_ITEM_TYPE_ETH,
+	RTE_FLOW_ITEM_TYPE_IPV4,
+	RTE_FLOW_ITEM_TYPE_UDP,
+	RTE_FLOW_ITEM_TYPE_L2TPV2,
+	RTE_FLOW_ITEM_TYPE_PPP,
+	RTE_FLOW_ITEM_TYPE_IPV4,
+	RTE_FLOW_ITEM_TYPE_UDP,
+	RTE_FLOW_ITEM_TYPE_END,
+};
+
+enum rte_flow_item_type iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv4_tcp[] = {
+	RTE_FLOW_ITEM_TYPE_ETH,
+	RTE_FLOW_ITEM_TYPE_IPV4,
+	RTE_FLOW_ITEM_TYPE_UDP,
+	RTE_FLOW_ITEM_TYPE_L2TPV2,
+	RTE_FLOW_ITEM_TYPE_PPP,
+	RTE_FLOW_ITEM_TYPE_IPV4,
+	RTE_FLOW_ITEM_TYPE_TCP,
+	RTE_FLOW_ITEM_TYPE_END,
+};
+
+enum rte_flow_item_type iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv6_udp[] = {
+	RTE_FLOW_ITEM_TYPE_ETH,
+	RTE_FLOW_ITEM_TYPE_IPV4,
+	RTE_FLOW_ITEM_TYPE_UDP,
+	RTE_FLOW_ITEM_TYPE_L2TPV2,
+	RTE_FLOW_ITEM_TYPE_PPP,
+	RTE_FLOW_ITEM_TYPE_IPV6,
+	RTE_FLOW_ITEM_TYPE_UDP,
+	RTE_FLOW_ITEM_TYPE_END,
+};
+
+enum rte_flow_item_type iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv6_tcp[] = {
+	RTE_FLOW_ITEM_TYPE_ETH,
+	RTE_FLOW_ITEM_TYPE_IPV4,
+	RTE_FLOW_ITEM_TYPE_UDP,
+	RTE_FLOW_ITEM_TYPE_L2TPV2,
+	RTE_FLOW_ITEM_TYPE_PPP,
+	RTE_FLOW_ITEM_TYPE_IPV6,
+	RTE_FLOW_ITEM_TYPE_TCP,
+	RTE_FLOW_ITEM_TYPE_END,
+};
+
+enum rte_flow_item_type iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv4[] = {
+	RTE_FLOW_ITEM_TYPE_ETH,
+	RTE_FLOW_ITEM_TYPE_IPV6,
+	RTE_FLOW_ITEM_TYPE_UDP,
+	RTE_FLOW_ITEM_TYPE_L2TPV2,
+	RTE_FLOW_ITEM_TYPE_PPP,
+	RTE_FLOW_ITEM_TYPE_IPV4,
+	RTE_FLOW_ITEM_TYPE_END,
+};
+
+enum rte_flow_item_type iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv6[] = {
+	RTE_FLOW_ITEM_TYPE_ETH,
+	RTE_FLOW_ITEM_TYPE_IPV6,
+	RTE_FLOW_ITEM_TYPE_UDP,
+	RTE_FLOW_ITEM_TYPE_L2TPV2,
+	RTE_FLOW_ITEM_TYPE_PPP,
+	RTE_FLOW_ITEM_TYPE_IPV6,
+	RTE_FLOW_ITEM_TYPE_END,
+};
+
+enum rte_flow_item_type iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv4_udp[] = {
+	RTE_FLOW_ITEM_TYPE_ETH,
+	RTE_FLOW_ITEM_TYPE_IPV6,
+	RTE_FLOW_ITEM_TYPE_UDP,
+	RTE_FLOW_ITEM_TYPE_L2TPV2,
+	RTE_FLOW_ITEM_TYPE_PPP,
+	RTE_FLOW_ITEM_TYPE_IPV4,
+	RTE_FLOW_ITEM_TYPE_UDP,
+	RTE_FLOW_ITEM_TYPE_END,
+};
+
+enum rte_flow_item_type iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv4_tcp[] = {
+	RTE_FLOW_ITEM_TYPE_ETH,
+	RTE_FLOW_ITEM_TYPE_IPV6,
+	RTE_FLOW_ITEM_TYPE_UDP,
+	RTE_FLOW_ITEM_TYPE_L2TPV2,
+	RTE_FLOW_ITEM_TYPE_PPP,
+	RTE_FLOW_ITEM_TYPE_IPV4,
+	RTE_FLOW_ITEM_TYPE_TCP,
+	RTE_FLOW_ITEM_TYPE_END,
+};
+
+enum rte_flow_item_type iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv6_udp[] = {
+	RTE_FLOW_ITEM_TYPE_ETH,
+	RTE_FLOW_ITEM_TYPE_IPV6,
+	RTE_FLOW_ITEM_TYPE_UDP,
+	RTE_FLOW_ITEM_TYPE_L2TPV2,
+	RTE_FLOW_ITEM_TYPE_PPP,
+	RTE_FLOW_ITEM_TYPE_IPV6,
+	RTE_FLOW_ITEM_TYPE_UDP,
+	RTE_FLOW_ITEM_TYPE_END,
+};
+
+enum rte_flow_item_type iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv6_tcp[] = {
+	RTE_FLOW_ITEM_TYPE_ETH,
+	RTE_FLOW_ITEM_TYPE_IPV6,
+	RTE_FLOW_ITEM_TYPE_UDP,
+	RTE_FLOW_ITEM_TYPE_L2TPV2,
+	RTE_FLOW_ITEM_TYPE_PPP,
+	RTE_FLOW_ITEM_TYPE_IPV6,
+	RTE_FLOW_ITEM_TYPE_TCP,
+	RTE_FLOW_ITEM_TYPE_END,
+};
+
+
+
 typedef struct iavf_flow_engine * (*parse_engine_t)(struct iavf_adapter *ad,
 		struct rte_flow *flow,
 		struct iavf_parser_list *parser_list,
diff --git a/drivers/net/iavf/iavf_generic_flow.h b/drivers/net/iavf/iavf_generic_flow.h
index 4794d1fb80..f2b54e1944 100644
--- a/drivers/net/iavf/iavf_generic_flow.h
+++ b/drivers/net/iavf/iavf_generic_flow.h
@@ -410,6 +410,21 @@ extern enum rte_flow_item_type iavf_pattern_eth_ipv6_gre_ipv6_tcp[];
 extern enum rte_flow_item_type iavf_pattern_eth_ipv6_gre_ipv4_udp[];
 extern enum rte_flow_item_type iavf_pattern_eth_ipv6_gre_ipv6_udp[];
 
+/* PPPoL2TPv2oUDP */
+extern enum rte_flow_item_type iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv4[];
+extern enum rte_flow_item_type iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv6[];
+extern enum rte_flow_item_type iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv4_udp[];
+extern enum rte_flow_item_type iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv4_tcp[];
+extern enum rte_flow_item_type iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv6_udp[];
+extern enum rte_flow_item_type iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv6_tcp[];
+extern enum rte_flow_item_type iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv4[];
+extern enum rte_flow_item_type iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv6[];
+extern enum rte_flow_item_type iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv4_udp[];
+extern enum rte_flow_item_type iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv4_tcp[];
+extern enum rte_flow_item_type iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv6_udp[];
+extern enum rte_flow_item_type iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv6_tcp[];
+
+
 extern const struct rte_flow_ops iavf_flow_ops;
 
 /* pattern structure */
diff --git a/drivers/net/iavf/iavf_hash.c b/drivers/net/iavf/iavf_hash.c
index 1f2d3772d1..01724cd569 100644
--- a/drivers/net/iavf/iavf_hash.c
+++ b/drivers/net/iavf/iavf_hash.c
@@ -34,6 +34,8 @@
 /* the second IP header of GTPoGRE */
 #define IAVF_PHINT_MID_IPV4			BIT_ULL(7)
 #define IAVF_PHINT_MID_IPV6			BIT_ULL(8)
+/* L2TPv2 */
+#define IAVF_PHINT_L2TPV2			BIT_ULL(9)
 
 #define IAVF_PHINT_GTPU_MSK	(IAVF_PHINT_GTPU	| \
 				 IAVF_PHINT_GTPU_EH	| \
@@ -164,6 +166,12 @@ iavf_hash_parse_pattern_action(struct iavf_adapter *ad,
 	VIRTCHNL_PROTO_HDR_ECPRI, \
 	FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_ECPRI_PC_RTC_ID), {BUFF_NOUSED} }
 
+#define proto_hdr_l2tpv2 { \
+	VIRTCHNL_PROTO_HDR_L2TPV2, 0, {BUFF_NOUSED} }
+
+#define proto_hdr_ppp { \
+	VIRTCHNL_PROTO_HDR_PPP, 0, {BUFF_NOUSED} }
+
 #define TUNNEL_LEVEL_OUTER		0
 #define TUNNEL_LEVEL_INNER		1
 
@@ -338,6 +346,52 @@ struct virtchnl_proto_hdrs ipv4_ecpri_tmplt = {
 	TUNNEL_LEVEL_OUTER, 3, {proto_hdr_ipv4, proto_hdr_udp, proto_hdr_ecpri}
 };
 
+struct virtchnl_proto_hdrs udp_l2tpv2_ppp_ipv4_tmplt = {
+	TUNNEL_LEVEL_INNER, 3,
+	{proto_hdr_l2tpv2,
+	 proto_hdr_ppp,
+	 proto_hdr_ipv4}
+};
+
+struct virtchnl_proto_hdrs udp_l2tpv2_ppp_ipv6_tmplt = {
+	TUNNEL_LEVEL_INNER, 3,
+	{proto_hdr_l2tpv2,
+	 proto_hdr_ppp,
+	 proto_hdr_ipv6}
+};
+
+struct virtchnl_proto_hdrs udp_l2tpv2_ppp_ipv4_udp_tmplt = {
+	TUNNEL_LEVEL_INNER, 4,
+	{proto_hdr_l2tpv2,
+	 proto_hdr_ppp,
+	 proto_hdr_ipv4_with_prot,
+	 proto_hdr_udp}
+};
+
+struct virtchnl_proto_hdrs udp_l2tpv2_ppp_ipv4_tcp_tmplt = {
+	TUNNEL_LEVEL_INNER, 4,
+	{proto_hdr_l2tpv2,
+	 proto_hdr_ppp,
+	 proto_hdr_ipv4_with_prot,
+	 proto_hdr_tcp}
+};
+
+struct virtchnl_proto_hdrs udp_l2tpv2_ppp_ipv6_udp_tmplt = {
+	TUNNEL_LEVEL_INNER, 4,
+	{proto_hdr_l2tpv2,
+	 proto_hdr_ppp,
+	 proto_hdr_ipv6_with_prot,
+	 proto_hdr_udp}
+};
+
+struct virtchnl_proto_hdrs udp_l2tpv2_ppp_ipv6_tcp_tmplt = {
+	TUNNEL_LEVEL_INNER, 4,
+	{proto_hdr_l2tpv2,
+	 proto_hdr_ppp,
+	 proto_hdr_ipv6_with_prot,
+	 proto_hdr_tcp}
+};
+
 /* rss type super set */
 
 /* IPv4 outer */
@@ -493,6 +547,13 @@ static struct iavf_pattern_match_item iavf_hash_pattern_list[] = {
 	{iavf_pattern_eth_ipv6_gre_ipv4_tcp,	IAVF_RSS_TYPE_INNER_IPV4_TCP, &inner_ipv4_tcp_tmplt},
 	{iavf_pattern_eth_ipv4_gre_ipv4_udp,	IAVF_RSS_TYPE_INNER_IPV4_UDP, &inner_ipv4_udp_tmplt},
 	{iavf_pattern_eth_ipv6_gre_ipv4_udp,	IAVF_RSS_TYPE_INNER_IPV4_UDP, &inner_ipv4_udp_tmplt},
+	{iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv4,	IAVF_RSS_TYPE_INNER_IPV4,	&udp_l2tpv2_ppp_ipv4_tmplt},
+	{iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv4_udp,	IAVF_RSS_TYPE_INNER_IPV4_UDP,	&udp_l2tpv2_ppp_ipv4_udp_tmplt},
+	{iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv4_tcp,	IAVF_RSS_TYPE_INNER_IPV4_TCP,	&udp_l2tpv2_ppp_ipv4_tcp_tmplt},
+	{iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv4,	IAVF_RSS_TYPE_INNER_IPV4,	&udp_l2tpv2_ppp_ipv4_tmplt},
+	{iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv4_udp,	IAVF_RSS_TYPE_INNER_IPV4_UDP,	&udp_l2tpv2_ppp_ipv4_udp_tmplt},
+	{iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv4_tcp,	IAVF_RSS_TYPE_INNER_IPV4_TCP,	&udp_l2tpv2_ppp_ipv4_tcp_tmplt},
+
 	/* IPv6 */
 	{iavf_pattern_eth_ipv6,				IAVF_RSS_TYPE_OUTER_IPV6,	&outer_ipv6_tmplt},
 	{iavf_pattern_eth_ipv6_frag_ext,		IAVF_RSS_TYPE_OUTER_IPV6_FRAG,	&outer_ipv6_frag_tmplt},
@@ -553,6 +614,13 @@ static struct iavf_pattern_match_item iavf_hash_pattern_list[] = {
 	{iavf_pattern_eth_ipv6_gre_ipv6_tcp,	IAVF_RSS_TYPE_INNER_IPV6_TCP, &inner_ipv6_tcp_tmplt},
 	{iavf_pattern_eth_ipv4_gre_ipv6_udp,	IAVF_RSS_TYPE_INNER_IPV6_UDP, &inner_ipv6_udp_tmplt},
 	{iavf_pattern_eth_ipv6_gre_ipv6_udp,	IAVF_RSS_TYPE_INNER_IPV6_UDP, &inner_ipv6_udp_tmplt},
+	{iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv6,	IAVF_RSS_TYPE_INNER_IPV6,	&udp_l2tpv2_ppp_ipv6_tmplt},
+	{iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv6_udp,	IAVF_RSS_TYPE_INNER_IPV6_UDP,	&udp_l2tpv2_ppp_ipv6_udp_tmplt},
+	{iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv6_tcp,	IAVF_RSS_TYPE_INNER_IPV6_TCP,	&udp_l2tpv2_ppp_ipv6_tcp_tmplt},
+	{iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv6,	IAVF_RSS_TYPE_INNER_IPV6,	&udp_l2tpv2_ppp_ipv6_tmplt},
+	{iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv6_udp,	IAVF_RSS_TYPE_INNER_IPV6_UDP,	&udp_l2tpv2_ppp_ipv6_udp_tmplt},
+	{iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv6_tcp,	IAVF_RSS_TYPE_INNER_IPV6_TCP,	&udp_l2tpv2_ppp_ipv6_tcp_tmplt},
+
 };
 
 static struct iavf_flow_engine iavf_hash_engine = {
@@ -687,13 +755,17 @@ iavf_hash_parse_pattern(const struct rte_flow_item pattern[], uint64_t *phint,
 
 		switch (item->type) {
 		case RTE_FLOW_ITEM_TYPE_IPV4:
-			if (!(*phint & IAVF_PHINT_GTPU_MSK) && !(*phint & IAVF_PHINT_GRE))
+			if (!(*phint & IAVF_PHINT_GTPU_MSK) &&
+			    !(*phint & IAVF_PHINT_GRE) &&
+			    !(*phint & IAVF_PHINT_L2TPV2))
 				*phint |= IAVF_PHINT_OUTER_IPV4;
 			if ((*phint & IAVF_PHINT_GRE) && !(*phint & IAVF_PHINT_GTPU_MSK))
 				*phint |= IAVF_PHINT_MID_IPV4;
 			break;
 		case RTE_FLOW_ITEM_TYPE_IPV6:
-			if (!(*phint & IAVF_PHINT_GTPU_MSK) && !(*phint & IAVF_PHINT_GRE))
+			if (!(*phint & IAVF_PHINT_GTPU_MSK) &&
+			    !(*phint & IAVF_PHINT_GRE) &&
+			    !(*phint & IAVF_PHINT_L2TPV2))
 				*phint |= IAVF_PHINT_OUTER_IPV6;
 			if ((*phint & IAVF_PHINT_GRE) && !(*phint & IAVF_PHINT_GTPU_MSK))
 				*phint |= IAVF_PHINT_MID_IPV6;
@@ -728,6 +800,10 @@ iavf_hash_parse_pattern(const struct rte_flow_item pattern[], uint64_t *phint,
 			break;
 		case RTE_FLOW_ITEM_TYPE_GRE:
 			*phint |= IAVF_PHINT_GRE;
+			break;
+		case RTE_FLOW_ITEM_TYPE_L2TPV2:
+			*phint |= IAVF_PHINT_L2TPV2;
+			break;
 		default:
 			break;
 		}
@@ -1050,12 +1126,40 @@ iavf_refine_proto_hdrs_by_pattern(struct virtchnl_proto_hdrs *proto_hdrs,
 	proto_hdrs->tunnel_level = tun_lvl;
 }
 
+static void
+iavf_refine_proto_hdrs_l2tpv2(struct virtchnl_proto_hdrs *proto_hdrs,
+			      uint64_t phint)
+{
+	struct virtchnl_proto_hdr *hdr1;
+	int i;
+
+	if (!(phint & IAVF_PHINT_L2TPV2))
+		return;
+
+	if (proto_hdrs->tunnel_level == TUNNEL_LEVEL_INNER) {
+		/* shift headers layer */
+		for (i = proto_hdrs->count - 1 + 1; i > 0; i--)
+			proto_hdrs->proto_hdr[i] = proto_hdrs->proto_hdr[i - 1];
+
+		/* adding outer ip header at layer 0 */
+		hdr1 = &proto_hdrs->proto_hdr[0];
+		hdr1->field_selector = 0;
+		proto_hdrs->count++;
+		proto_hdrs->tunnel_level = TUNNEL_LEVEL_OUTER;
+		if (phint & IAVF_PHINT_OUTER_IPV4)
+			VIRTCHNL_SET_PROTO_HDR_TYPE(hdr1, IPV4);
+		else if (phint & IAVF_PHINT_OUTER_IPV6)
+			VIRTCHNL_SET_PROTO_HDR_TYPE(hdr1, IPV6);
+	}
+}
+
 static void iavf_refine_proto_hdrs(struct virtchnl_proto_hdrs *proto_hdrs,
 				   uint64_t rss_type, uint64_t phint)
 {
 	iavf_refine_proto_hdrs_l234(proto_hdrs, rss_type);
 	iavf_refine_proto_hdrs_by_pattern(proto_hdrs, phint);
 	iavf_refine_proto_hdrs_gtpu(proto_hdrs, rss_type);
+	iavf_refine_proto_hdrs_l2tpv2(proto_hdrs, phint);
 }
 
 static uint64_t invalid_rss_comb[] = {
-- 
2.25.1


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

* [dpdk-dev] [PATCH v8 3/3] app/testpmd: support L2TPv2 and PPP protocol pattern
  2021-10-21 10:05             ` [dpdk-dev] [PATCH v8 0/3] support PPPoL2TPv2oUDP RSS Hash Jie Wang
  2021-10-21 10:05               ` [dpdk-dev] [PATCH v8 1/3] ethdev: support L2TPv2 and PPP procotol Jie Wang
  2021-10-21 10:05               ` [dpdk-dev] [PATCH v8 2/3] net/iavf: support PPPoL2TPv2oUDP RSS Hash Jie Wang
@ 2021-10-21 10:05               ` Jie Wang
  2021-10-21 10:49               ` [dpdk-dev] [PATCH v9 0/3] support PPPoL2TPv2oUDP RSS Hash Jie Wang
  3 siblings, 0 replies; 71+ messages in thread
From: Jie Wang @ 2021-10-21 10:05 UTC (permalink / raw)
  To: dev
  Cc: orika, ferruh.yigit, thomas, andrew.rybchenko, xiaoyun.li,
	stevex.yang, jingjing.wu, beilei.xing, wenjun1.wu, qi.z.zhang,
	Jie Wang

Add support for test-pmd to parse protocol pattern L2TPv2 and PPP.

Signed-off-by: Wenjun Wu <wenjun1.wu@intel.com>
Signed-off-by: Jie Wang <jie1x.wang@intel.com>
---
 app/test-pmd/cmdline_flow.c                 | 251 ++++++++++++++++++++
 doc/guides/testpmd_app_ug/testpmd_funcs.rst |  28 +++
 2 files changed, 279 insertions(+)

diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
index 5437975837..d8218771fb 100644
--- a/app/test-pmd/cmdline_flow.c
+++ b/app/test-pmd/cmdline_flow.c
@@ -321,6 +321,23 @@ enum index {
 	ITEM_FLEX,
 	ITEM_FLEX_ITEM_HANDLE,
 	ITEM_FLEX_PATTERN_HANDLE,
+	ITEM_L2TPV2,
+	ITEM_L2TPV2_COMMON,
+	ITEM_L2TPV2_COMMON_TYPE,
+	ITEM_L2TPV2_COMMON_TYPE_DATA_L,
+	ITEM_L2TPV2_COMMON_TYPE_CTRL,
+	ITEM_L2TPV2_MSG_DATA_L_LENGTH,
+	ITEM_L2TPV2_MSG_DATA_L_TUNNEL_ID,
+	ITEM_L2TPV2_MSG_DATA_L_SESSION_ID,
+	ITEM_L2TPV2_MSG_CTRL_LENGTH,
+	ITEM_L2TPV2_MSG_CTRL_TUNNEL_ID,
+	ITEM_L2TPV2_MSG_CTRL_SESSION_ID,
+	ITEM_L2TPV2_MSG_CTRL_NS,
+	ITEM_L2TPV2_MSG_CTRL_NR,
+	ITEM_PPP,
+	ITEM_PPP_ADDR,
+	ITEM_PPP_CTRL,
+	ITEM_PPP_PROTO_ID,
 
 	/* Validate/create actions. */
 	ACTIONS,
@@ -1042,6 +1059,8 @@ static const enum index next_item[] = {
 	ITEM_PORT_REPRESENTOR,
 	ITEM_REPRESENTED_PORT,
 	ITEM_FLEX,
+	ITEM_L2TPV2,
+	ITEM_PPP,
 	END_SET,
 	ZERO,
 };
@@ -1429,6 +1448,31 @@ static const enum index item_flex[] = {
 	ZERO,
 };
 
+static const enum index item_l2tpv2[] = {
+	ITEM_L2TPV2_COMMON,
+	ITEM_NEXT,
+	ZERO,
+};
+
+static const enum index item_l2tpv2_common[] = {
+	ITEM_L2TPV2_COMMON_TYPE,
+	ZERO,
+};
+
+static const enum index item_l2tpv2_common_type[] = {
+	ITEM_L2TPV2_COMMON_TYPE_DATA_L,
+	ITEM_L2TPV2_COMMON_TYPE_CTRL,
+	ZERO,
+};
+
+static const enum index item_ppp[] = {
+	ITEM_PPP_ADDR,
+	ITEM_PPP_CTRL,
+	ITEM_PPP_PROTO_ID,
+	ITEM_NEXT,
+	ZERO,
+};
+
 static const enum index next_action[] = {
 	ACTION_END,
 	ACTION_VOID,
@@ -1815,6 +1859,9 @@ static int parse_vc_conf(struct context *, const struct token *,
 static int parse_vc_item_ecpri_type(struct context *, const struct token *,
 				    const char *, unsigned int,
 				    void *, unsigned int);
+static int parse_vc_item_l2tpv2_type(struct context *, const struct token *,
+				    const char *, unsigned int,
+				    void *, unsigned int);
 static int parse_vc_action_meter_color_type(struct context *,
 					const struct token *,
 					const char *, unsigned int, void *,
@@ -3789,6 +3836,153 @@ static const struct token token_list[] = {
 			     NEXT_ENTRY(ITEM_PARAM_IS)),
 		.args = ARGS(ARGS_ENTRY(struct rte_flow_item_flex, pattern)),
 	},
+	[ITEM_L2TPV2] = {
+		.name = "l2tpv2",
+		.help = "match L2TPv2 header",
+		.priv = PRIV_ITEM(L2TPV2, sizeof(struct rte_flow_item_l2tpv2)),
+		.next = NEXT(item_l2tpv2),
+		.call = parse_vc,
+	},
+	[ITEM_L2TPV2_COMMON] = {
+		.name = "common",
+		.help = "L2TPv2 common header",
+		.next = NEXT(item_l2tpv2_common),
+	},
+	[ITEM_L2TPV2_COMMON_TYPE] = {
+		.name = "type",
+		.help = "type of common header",
+		.next = NEXT(item_l2tpv2_common_type),
+		.args = ARGS(ARG_ENTRY_HTON(struct rte_flow_item_l2tpv2)),
+	},
+	[ITEM_L2TPV2_COMMON_TYPE_DATA_L] = {
+		.name = "data_l",
+		.help = "Type #6: data message with length option",
+		.next = NEXT(NEXT_ENTRY(ITEM_L2TPV2_MSG_DATA_L_LENGTH,
+					ITEM_L2TPV2_MSG_DATA_L_TUNNEL_ID,
+					ITEM_L2TPV2_MSG_DATA_L_SESSION_ID,
+					ITEM_NEXT)),
+		.call = parse_vc_item_l2tpv2_type,
+	},
+	[ITEM_L2TPV2_MSG_DATA_L_LENGTH] = {
+		.name = "length",
+		.help = "message length",
+		.next = NEXT(NEXT_ENTRY(ITEM_L2TPV2_MSG_DATA_L_LENGTH,
+					ITEM_L2TPV2_COMMON, ITEM_NEXT),
+			     NEXT_ENTRY(COMMON_UNSIGNED),
+			     item_param),
+		.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2,
+					     hdr.type6.length)),
+	},
+	[ITEM_L2TPV2_MSG_DATA_L_TUNNEL_ID] = {
+		.name = "tunnel_id",
+		.help = "tunnel identifier",
+		.next = NEXT(NEXT_ENTRY(ITEM_L2TPV2_MSG_DATA_L_TUNNEL_ID,
+					ITEM_L2TPV2_COMMON, ITEM_NEXT),
+			     NEXT_ENTRY(COMMON_UNSIGNED),
+			     item_param),
+		.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2,
+					     hdr.type6.tunnel_id)),
+	},
+	[ITEM_L2TPV2_MSG_DATA_L_SESSION_ID] = {
+		.name = "session_id",
+		.help = "session identifier",
+		.next = NEXT(NEXT_ENTRY(ITEM_L2TPV2_MSG_DATA_L_SESSION_ID,
+					ITEM_L2TPV2_COMMON, ITEM_NEXT),
+			     NEXT_ENTRY(COMMON_UNSIGNED),
+			     item_param),
+		.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2,
+					     hdr.type6.session_id)),
+	},
+	[ITEM_L2TPV2_COMMON_TYPE_CTRL] = {
+		.name = "control",
+		.help = "Type #3: conrtol message contains length, ns, nr options",
+		.next = NEXT(NEXT_ENTRY(ITEM_L2TPV2_MSG_CTRL_LENGTH,
+					ITEM_L2TPV2_MSG_CTRL_TUNNEL_ID,
+					ITEM_L2TPV2_MSG_CTRL_SESSION_ID,
+					ITEM_L2TPV2_MSG_CTRL_NS,
+					ITEM_L2TPV2_MSG_CTRL_NR,
+					ITEM_NEXT)),
+		.call = parse_vc_item_l2tpv2_type,
+	},
+	[ITEM_L2TPV2_MSG_CTRL_LENGTH] = {
+		.name = "length",
+		.help = "message length",
+		.next = NEXT(NEXT_ENTRY(ITEM_L2TPV2_MSG_CTRL_LENGTH,
+					ITEM_L2TPV2_COMMON, ITEM_NEXT),
+			     NEXT_ENTRY(COMMON_UNSIGNED),
+			     item_param),
+		.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2,
+					     hdr.type3.length)),
+	},
+	[ITEM_L2TPV2_MSG_CTRL_TUNNEL_ID] = {
+		.name = "tunnel_id",
+		.help = "tunnel identifier",
+		.next = NEXT(NEXT_ENTRY(ITEM_L2TPV2_MSG_CTRL_TUNNEL_ID,
+					ITEM_L2TPV2_COMMON, ITEM_NEXT),
+			     NEXT_ENTRY(COMMON_UNSIGNED),
+			     item_param),
+		.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2,
+					     hdr.type3.tunnel_id)),
+	},
+	[ITEM_L2TPV2_MSG_CTRL_SESSION_ID] = {
+		.name = "session_id",
+		.help = "session identifier",
+		.next = NEXT(NEXT_ENTRY(ITEM_L2TPV2_MSG_CTRL_SESSION_ID,
+					ITEM_L2TPV2_COMMON, ITEM_NEXT),
+			     NEXT_ENTRY(COMMON_UNSIGNED),
+			     item_param),
+		.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2,
+					     hdr.type3.session_id)),
+	},
+	[ITEM_L2TPV2_MSG_CTRL_NS] = {
+		.name = "ns",
+		.help = "sequence number for message",
+		.next = NEXT(NEXT_ENTRY(ITEM_L2TPV2_MSG_CTRL_NS,
+					ITEM_L2TPV2_COMMON, ITEM_NEXT),
+			     NEXT_ENTRY(COMMON_UNSIGNED),
+			     item_param),
+		.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2,
+					     hdr.type3.ns)),
+	},
+	[ITEM_L2TPV2_MSG_CTRL_NR] = {
+		.name = "nr",
+		.help = "sequence number for next receive message",
+		.next = NEXT(NEXT_ENTRY(ITEM_L2TPV2_MSG_CTRL_NS,
+					ITEM_L2TPV2_COMMON, ITEM_NEXT),
+			     NEXT_ENTRY(COMMON_UNSIGNED),
+			     item_param),
+		.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2,
+					     hdr.type3.nr)),
+	},
+	[ITEM_PPP] = {
+		.name = "ppp",
+		.help = "match PPP header",
+		.priv = PRIV_ITEM(PPP, sizeof(struct rte_flow_item_ppp)),
+		.next = NEXT(item_ppp),
+		.call = parse_vc,
+	},
+	[ITEM_PPP_ADDR] = {
+		.name = "addr",
+		.help = "PPP address",
+		.next = NEXT(item_ppp, NEXT_ENTRY(COMMON_UNSIGNED),
+			     item_param),
+		.args = ARGS(ARGS_ENTRY(struct rte_flow_item_ppp, hdr.addr)),
+	},
+	[ITEM_PPP_CTRL] = {
+		.name = "ctrl",
+		.help = "PPP control",
+		.next = NEXT(item_ppp, NEXT_ENTRY(COMMON_UNSIGNED),
+			     item_param),
+		.args = ARGS(ARGS_ENTRY(struct rte_flow_item_ppp, hdr.ctrl)),
+	},
+	[ITEM_PPP_PROTO_ID] = {
+		.name = "proto_id",
+		.help = "PPP protocol identifier",
+		.next = NEXT(item_ppp, NEXT_ENTRY(COMMON_UNSIGNED),
+			     item_param),
+		.args = ARGS(ARGS_ENTRY(struct rte_flow_item_ppp,
+					hdr.proto_id)),
+	},
 	/* Validate/create actions. */
 	[ACTIONS] = {
 		.name = "actions",
@@ -5676,6 +5870,57 @@ parse_vc_item_ecpri_type(struct context *ctx, const struct token *token,
 	return len;
 }
 
+/** Parse L2TPv2 common header type field. */
+static int
+parse_vc_item_l2tpv2_type(struct context *ctx, const struct token *token,
+			 const char *str, unsigned int len,
+			 void *buf, unsigned int size)
+{
+	struct rte_flow_item_l2tpv2 *l2tpv2;
+	struct rte_flow_item_l2tpv2 *l2tpv2_mask;
+	struct rte_flow_item *item;
+	uint32_t data_size;
+	uint8_t msg_type = 0;
+	struct buffer *out = buf;
+	const struct arg *arg;
+
+	(void)size;
+	/* Token name must match. */
+	if (parse_default(ctx, token, str, len, NULL, 0) < 0)
+		return -1;
+	switch (ctx->curr) {
+	case ITEM_L2TPV2_COMMON_TYPE_DATA_L:
+		msg_type |= 0x4000;
+		break;
+	case ITEM_L2TPV2_COMMON_TYPE_CTRL:
+		msg_type |= 0xC800;
+		break;
+	default:
+		return -1;
+	}
+	if (!ctx->object)
+		return len;
+	arg = pop_args(ctx);
+	if (!arg)
+		return -1;
+	l2tpv2 = (struct rte_flow_item_l2tpv2 *)out->args.vc.data;
+	l2tpv2->hdr.common.flags_version |= msg_type;
+	data_size = ctx->objdata / 3; /* spec, last, mask */
+	l2tpv2_mask = (struct rte_flow_item_l2tpv2 *)(out->args.vc.data +
+						    (data_size * 2));
+	l2tpv2_mask->hdr.common.flags_version = 0xFFFF;
+	if (arg->hton) {
+		l2tpv2->hdr.common.flags_version =
+			rte_cpu_to_be_16(l2tpv2->hdr.common.flags_version);
+		l2tpv2_mask->hdr.common.flags_version =
+		    rte_cpu_to_be_16(l2tpv2_mask->hdr.common.flags_version);
+	}
+	item = &out->args.vc.pattern[out->args.vc.pattern_n - 1];
+	item->spec = l2tpv2;
+	item->mask = l2tpv2_mask;
+	return len;
+}
+
 /** Parse meter color action type. */
 static int
 parse_vc_action_meter_color_type(struct context *ctx, const struct token *token,
@@ -8701,6 +8946,12 @@ flow_item_default_mask(const struct rte_flow_item *item)
 	case RTE_FLOW_ITEM_TYPE_REPRESENTED_PORT:
 		mask = &rte_flow_item_ethdev_mask;
 		break;
+	case RTE_FLOW_ITEM_TYPE_L2TPV2:
+		mask = &rte_flow_item_l2tpv2_mask;
+		break;
+	case RTE_FLOW_ITEM_TYPE_PPP:
+		mask = &rte_flow_item_ppp_mask;
+		break;
 	default:
 		break;
 	}
diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
index 6d127d9a7b..31d6e1b293 100644
--- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
+++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
@@ -3810,6 +3810,20 @@ This section lists supported pattern items and their attributes, if any.
 
   - ``ethdev_port_id {unsigned}``: ethdev port ID
 
+- ``l2tpv2``: match L2TPv2 header.
+
+  - ``length {unsigned}``: L2TPv2 option length.
+  - ``tunnel_id {unsigned}``: L2TPv2 tunnel identifier.
+  - ``session_id {unsigned}``: L2TPv2 session identifier.
+  - ``ns {unsigned}``: L2TPv2 option ns.
+  - ``nr {unsigned}``: L2TPv2 option nr.
+
+- ``ppp``: match PPP header.
+
+  - ``addr {unsigned}``: PPP address.
+  - ``ctrl {unsigned}``: PPP control.
+  - ``proto_id {unsigned}``: PPP protocol identifier.
+
 Actions list
 ^^^^^^^^^^^^
 
@@ -5036,6 +5050,20 @@ The meter policy action list: ``green -> green, yellow -> yellow, red -> red``.
    testpmd> create port meter 0 1 13 1 yes 0xffff 0 0
    testpmd> flow create 0 priority 0 ingress group 1 pattern eth / end actions meter mtr_id 1 / end
 
+Sample PPPoL2TPv2oUDP RSS rules
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+PPPoL2TPv2oUDP RSS rules can be created by the following commands::
+
+ testpmd> flow create 0 ingress pattern eth / ipv4 / udp / l2tpv2 / ppp / ipv4
+          / end actions rss types ipv4 end queues end / end
+ testpmd> flow create 0 ingress pattern eth / ipv4 / udp / l2tpv2 / ppp / ipv6
+          / udp / end actions rss types ipv6-udp end queues end / end
+ testpmd> flow create 0 ingress pattern eth / ipv6 / udp / l2tpv2 / ppp / ipv4
+          / tcp / end actions rss types ipv4-tcp end queues end / end
+ testpmd> flow create 0 ingress pattern eth / ipv6 / udp / l2tpv2 / ppp / ipv6
+          / end actions rss types ipv6 end queues end / end
+
 BPF Functions
 --------------
 
-- 
2.25.1


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

* Re: [dpdk-dev] [PATCH v8 1/3] ethdev: support L2TPv2 and PPP procotol
  2021-10-21 10:05               ` [dpdk-dev] [PATCH v8 1/3] ethdev: support L2TPv2 and PPP procotol Jie Wang
@ 2021-10-21 10:13                 ` Andrew Rybchenko
  0 siblings, 0 replies; 71+ messages in thread
From: Andrew Rybchenko @ 2021-10-21 10:13 UTC (permalink / raw)
  To: Jie Wang, dev
  Cc: orika, ferruh.yigit, thomas, xiaoyun.li, stevex.yang,
	jingjing.wu, beilei.xing, wenjun1.wu, qi.z.zhang

On 10/21/21 1:05 PM, Jie Wang wrote:
> Added flow pattern items and header formats of L2TPv2 and PPP.
> 
> Acked-by: Ori Kam <orika@nvidia.com>

Acks should go after Signed-off-by.

> Signed-off-by: Wenjun Wu <wenjun1.wu@intel.com>
> Signed-off-by: Jie Wang <jie1x.wang@intel.com>

with a couple of nits fixed

Acked-by: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>

[snip]

> diff --git a/lib/ethdev/rte_flow.h b/lib/ethdev/rte_flow.h
> index 64ed7f2618..300e99e16b 100644
> --- a/lib/ethdev/rte_flow.h
> +++ b/lib/ethdev/rte_flow.h

[snip]

> @@ -1900,6 +1916,55 @@ static const struct rte_flow_item_ethdev rte_flow_item_ethdev_mask = {
>  };
>  #endif
>  
> +/**
> + * @warning
> + * @b EXPERIMENTAL: this structure may change without prior notice

Empty line is required between EXPERIMENTAL and item name.

> + * RTE_FLOW_ITEM_TYPE_L2TPV2
> + *
> + * Matches L2TPv2 Header
> + */
> +struct rte_flow_item_l2tpv2 {
> +	struct rte_l2tpv2_combined_msg_hdr hdr;
> +};
> +
> +/** Default mask for RTE_FLOW_ITEM_TYPE_L2TPV2. */
> +#ifndef __cplusplus
> +static const struct rte_flow_item_l2tpv2 rte_flow_item_l2tpv2_mask = {
> +	/*
> +	 * flags and version bit mask
> +	 * 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0
> +	 * T L x x S x O P x x x x V V V V
> +	 */
> +	.hdr = {
> +		.common = {
> +			.flags_version = RTE_BE16(0xcb0f),
> +		},
> +	},
> +};
> +#endif
> +
> +/**
> + * @warning
> + * @b EXPERIMENTAL: this structure may change without prior notice

here too

[snip]

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

* [dpdk-dev] [PATCH v9 0/3] support PPPoL2TPv2oUDP RSS Hash
  2021-10-21 10:05             ` [dpdk-dev] [PATCH v8 0/3] support PPPoL2TPv2oUDP RSS Hash Jie Wang
                                 ` (2 preceding siblings ...)
  2021-10-21 10:05               ` [dpdk-dev] [PATCH v8 3/3] app/testpmd: support L2TPv2 and PPP protocol pattern Jie Wang
@ 2021-10-21 10:49               ` Jie Wang
  2021-10-21 10:49                 ` [dpdk-dev] [PATCH v9 1/3] ethdev: support L2TPv2 and PPP procotol Jie Wang
                                   ` (3 more replies)
  3 siblings, 4 replies; 71+ messages in thread
From: Jie Wang @ 2021-10-21 10:49 UTC (permalink / raw)
  To: dev
  Cc: orika, ferruh.yigit, thomas, andrew.rybchenko, xiaoyun.li,
	stevex.yang, jingjing.wu, beilei.xing, wenjun1.wu, qi.z.zhang,
	Jie Wang

Support IAVF PPPoL2TPv2oUDP RSS Hash. Required to distribute packets
based on inner IP src+dest address and TCP/UDP src+dest port.

---
v9: 
 * update comments and commit log.
 * remove unnecessary '__rte_packed'.
v8:
 * added '__rte_packed' in new protocol header.
 * update the comment in new protocol header file.
V7:
 * update ini file.
 * modify irregular spelling.
v6:
 * update release notes.
 * update lib/net/meson.build.
 * update testpmd_funcs.rst.
 * update doxygen comments in header files.
 * update doc/api/doxy-api-index.md.
v5: update release notes.
v4:
 * update commit log.
 * redefine PPP protocol header.
 * delete l2tpv2_encap.
v3:
 * add testpmd match PPP and L2TPv2 protocol header fields value.
 * add the code of l2tpv2_encap.
 * update the title of ethdev patch and adjust the position of
   the added code.
v2:
 * update the rte_flow.rst and release notes.
 * update l2tpv2 header format.

Jie Wang (3):
  ethdev: support L2TPv2 and PPP procotol
  net/iavf: support PPPoL2TPv2oUDP RSS Hash
  app/testpmd: support L2TPv2 and PPP protocol pattern

 app/test-pmd/cmdline_flow.c                 | 251 ++++++++++++++++++++
 doc/api/doxy-api-index.md                   |   2 +
 doc/guides/nics/features/default.ini        |   2 +
 doc/guides/nics/features/iavf.ini           |   2 +
 doc/guides/prog_guide/rte_flow.rst          |  25 ++
 doc/guides/rel_notes/release_21_11.rst      |   5 +
 doc/guides/testpmd_app_ug/testpmd_funcs.rst |  28 +++
 drivers/net/iavf/iavf_generic_flow.c        | 131 ++++++++++
 drivers/net/iavf/iavf_generic_flow.h        |  15 ++
 drivers/net/iavf/iavf_hash.c                | 108 ++++++++-
 lib/ethdev/rte_flow.c                       |   2 +
 lib/ethdev/rte_flow.h                       |  67 ++++++
 lib/net/meson.build                         |   2 +
 lib/net/rte_l2tpv2.h                        | 234 ++++++++++++++++++
 lib/net/rte_ppp.h                           |  34 +++
 15 files changed, 906 insertions(+), 2 deletions(-)
 create mode 100644 lib/net/rte_l2tpv2.h
 create mode 100644 lib/net/rte_ppp.h

-- 
2.25.1


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

* [dpdk-dev] [PATCH v9 1/3] ethdev: support L2TPv2 and PPP procotol
  2021-10-21 10:49               ` [dpdk-dev] [PATCH v9 0/3] support PPPoL2TPv2oUDP RSS Hash Jie Wang
@ 2021-10-21 10:49                 ` Jie Wang
  2021-10-21 12:16                   ` Ferruh Yigit
  2021-10-21 10:49                 ` [dpdk-dev] [PATCH v9 2/3] net/iavf: support PPPoL2TPv2oUDP RSS Hash Jie Wang
                                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 71+ messages in thread
From: Jie Wang @ 2021-10-21 10:49 UTC (permalink / raw)
  To: dev
  Cc: orika, ferruh.yigit, thomas, andrew.rybchenko, xiaoyun.li,
	stevex.yang, jingjing.wu, beilei.xing, wenjun1.wu, qi.z.zhang,
	Jie Wang

Added flow pattern items and header formats of L2TPv2 and PPP.

Signed-off-by: Wenjun Wu <wenjun1.wu@intel.com>
Signed-off-by: Jie Wang <jie1x.wang@intel.com>
Acked-by: Ori Kam <orika@nvidia.com>
Acked-by: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>
---
 doc/api/doxy-api-index.md              |   2 +
 doc/guides/nics/features/default.ini   |   2 +
 doc/guides/prog_guide/rte_flow.rst     |  25 +++
 doc/guides/rel_notes/release_21_11.rst |   4 +
 lib/ethdev/rte_flow.c                  |   2 +
 lib/ethdev/rte_flow.h                  |  67 +++++++
 lib/net/meson.build                    |   2 +
 lib/net/rte_l2tpv2.h                   | 234 +++++++++++++++++++++++++
 lib/net/rte_ppp.h                      |  34 ++++
 9 files changed, 372 insertions(+)
 create mode 100644 lib/net/rte_l2tpv2.h
 create mode 100644 lib/net/rte_ppp.h

diff --git a/doc/api/doxy-api-index.md b/doc/api/doxy-api-index.md
index 1992107a03..42db196afe 100644
--- a/doc/api/doxy-api-index.md
+++ b/doc/api/doxy-api-index.md
@@ -121,6 +121,8 @@ The public API headers are grouped by topics:
   [VXLAN]              (@ref rte_vxlan.h),
   [Geneve]             (@ref rte_geneve.h),
   [eCPRI]              (@ref rte_ecpri.h)
+  [L2TPv2]             (@ref rte_l2tpv2.h)
+  [PPP]                (@ref rte_ppp.h)
 
 - **QoS**:
   [metering]           (@ref rte_meter.h),
diff --git a/doc/guides/nics/features/default.ini b/doc/guides/nics/features/default.ini
index 09914b1ad3..8e6a28c419 100644
--- a/doc/guides/nics/features/default.ini
+++ b/doc/guides/nics/features/default.ini
@@ -110,6 +110,7 @@ ipv4                 =
 ipv6                 =
 ipv6_ext             =
 ipv6_frag_ext        =
+l2tpv2               =
 l2tpv3oip            =
 mark                 =
 meta                 =
@@ -121,6 +122,7 @@ pfcp                 =
 phy_port             =
 port_id              =
 port_representor     =
+ppp                  =
 pppoed               =
 pppoes               =
 pppoe_proto_id       =
diff --git a/doc/guides/prog_guide/rte_flow.rst b/doc/guides/prog_guide/rte_flow.rst
index aeba374182..a2169517c3 100644
--- a/doc/guides/prog_guide/rte_flow.rst
+++ b/doc/guides/prog_guide/rte_flow.rst
@@ -1573,6 +1573,31 @@ rte_flow_flex_item_create() routine.
   as padded with trailing zeroes up to full configured length, both for
   value and mask.
 
+Item: ``L2TPV2``
+^^^^^^^^^^^^^^^^^^^
+
+Matches a L2TPv2 header.
+
+- ``flags_version``: flags(12b), version(4b).
+- ``length``: total length of the message.
+- ``tunnel_id``: identifier for the control connection.
+- ``session_id``: identifier for a session within a tunnel.
+- ``ns``: sequence number for this date or control message.
+- ``nr``: sequence number expected in the next control message to be received.
+- ``offset_size``: offset of payload data.
+- ``offset_padding``: offset padding, variable length.
+- Default ``mask`` matches flags_version only.
+
+Item: ``PPP``
+^^^^^^^^^^^^^^^^^^^
+
+Matches a PPP header.
+
+- ``addr``: PPP address.
+- ``ctrl``: PPP control.
+- ``proto_id``: PPP protocol identifier.
+- Default ``mask`` matches addr, ctrl, proto_id.
+
 Actions
 ~~~~~~~
 
diff --git a/doc/guides/rel_notes/release_21_11.rst b/doc/guides/rel_notes/release_21_11.rst
index 041383ee2a..283770131c 100644
--- a/doc/guides/rel_notes/release_21_11.rst
+++ b/doc/guides/rel_notes/release_21_11.rst
@@ -105,6 +105,10 @@ New Features
 
   Added an ethdev API which can help users get device configuration.
 
+* **Added L2TPv2 and PPP protocol support in rte_flow.**
+
+  Added flow pattern items and header formats of L2TPv2 and PPP protocol.
+
 * **Updated AF_XDP PMD.**
 
   * Disabled secondary process support.
diff --git a/lib/ethdev/rte_flow.c b/lib/ethdev/rte_flow.c
index bcf0513b3c..d268784532 100644
--- a/lib/ethdev/rte_flow.c
+++ b/lib/ethdev/rte_flow.c
@@ -156,6 +156,8 @@ static const struct rte_flow_desc_data rte_flow_desc_item[] = {
 	MK_FLOW_ITEM(REPRESENTED_PORT, sizeof(struct rte_flow_item_ethdev)),
 	MK_FLOW_ITEM_FN(FLEX, sizeof(struct rte_flow_item_flex),
 			rte_flow_item_flex_conv),
+	MK_FLOW_ITEM(L2TPV2, sizeof(struct rte_flow_item_l2tpv2)),
+	MK_FLOW_ITEM(PPP, sizeof(struct rte_flow_item_ppp)),
 };
 
 /** Generate flow_action[] entry. */
diff --git a/lib/ethdev/rte_flow.h b/lib/ethdev/rte_flow.h
index 64ed7f2618..db3392bf97 100644
--- a/lib/ethdev/rte_flow.h
+++ b/lib/ethdev/rte_flow.h
@@ -35,6 +35,8 @@
 #include <rte_mbuf_dyn.h>
 #include <rte_meter.h>
 #include <rte_gtp.h>
+#include <rte_l2tpv2.h>
+#include <rte_ppp.h>
 
 #ifdef __cplusplus
 extern "C" {
@@ -644,6 +646,20 @@ enum rte_flow_item_type {
 	 * @see struct rte_flow_item_flex.
 	 */
 	RTE_FLOW_ITEM_TYPE_FLEX,
+
+	/**
+	 * Matches L2TPv2 Header.
+	 *
+	 * See struct rte_flow_item_l2tpv2.
+	 */
+	RTE_FLOW_ITEM_TYPE_L2TPV2,
+
+	/**
+	 * Matches PPP Header.
+	 *
+	 * See struct rte_flow_item_ppp.
+	 */
+	RTE_FLOW_ITEM_TYPE_PPP,
 };
 
 /**
@@ -1900,6 +1916,57 @@ static const struct rte_flow_item_ethdev rte_flow_item_ethdev_mask = {
 };
 #endif
 
+/**
+ * @warning
+ * @b EXPERIMENTAL: this structure may change without prior notice
+ *
+ * RTE_FLOW_ITEM_TYPE_L2TPV2
+ *
+ * Matches L2TPv2 Header
+ */
+struct rte_flow_item_l2tpv2 {
+	struct rte_l2tpv2_combined_msg_hdr hdr;
+};
+
+/** Default mask for RTE_FLOW_ITEM_TYPE_L2TPV2. */
+#ifndef __cplusplus
+static const struct rte_flow_item_l2tpv2 rte_flow_item_l2tpv2_mask = {
+	/*
+	 * flags and version bit mask
+	 * 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0
+	 * T L x x S x O P x x x x V V V V
+	 */
+	.hdr = {
+		.common = {
+			.flags_version = RTE_BE16(0xcb0f),
+		},
+	},
+};
+#endif
+
+/**
+ * @warning
+ * @b EXPERIMENTAL: this structure may change without prior notice
+ *
+ * RTE_FLOW_ITEM_TYPE_PPP
+ *
+ * Matches PPP Header
+ */
+struct rte_flow_item_ppp {
+	struct rte_ppp_hdr hdr;
+};
+
+/** Default mask for RTE_FLOW_ITEM_TYPE_PPP. */
+#ifndef __cplusplus
+static const struct rte_flow_item_ppp rte_flow_item_ppp_mask = {
+	.hdr = {
+		.addr = 0xff,
+		.ctrl = 0xff,
+		.proto_id = RTE_BE16(0xffff),
+	}
+};
+#endif
+
 /**
  * Matching pattern item definition.
  *
diff --git a/lib/net/meson.build b/lib/net/meson.build
index a4e395e9c5..e899846578 100644
--- a/lib/net/meson.build
+++ b/lib/net/meson.build
@@ -19,6 +19,8 @@ headers = files(
         'rte_higig.h',
         'rte_ecpri.h',
         'rte_geneve.h',
+        'rte_l2tpv2.h',
+        'rte_ppp.h',
 )
 
 sources = files(
diff --git a/lib/net/rte_l2tpv2.h b/lib/net/rte_l2tpv2.h
new file mode 100644
index 0000000000..4634964820
--- /dev/null
+++ b/lib/net/rte_l2tpv2.h
@@ -0,0 +1,234 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2021 Intel Corporation.
+ */
+
+#ifndef _RTE_L2TPV2_H_
+#define _RTE_L2TPV2_H_
+
+/**
+ * @file
+ *
+ * L2TP header:
+ *
+ * `-0--------------------1----------------2-------------------3`
+ *
+ * `-0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1`
+ *
+ * `+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+`
+ *
+ * `|T|L|x|x|S|x|O|P|x|x|x|x|--Ver--|-----------Length (opt)--------|`
+ *
+ * `+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+`
+ *
+ * `|-----------Tunnel ID-----------|-----------Session ID----------|`
+ *
+ * `+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+`
+ *
+ * `|-----------Ns (opt)------------|-----------Nr (opt)------------|`
+ *
+ * `+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+`
+ *
+ * `|---------Offset Size (opt)-----|---------Offset pad... (opt)`
+ *
+ * `+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+`
+ *
+ * The Type (T) bit indicates the type of message. It is set to 0 for a data
+ * message and 1 for a control message.
+ *
+ * If the Length (L) bit is 1, the Length field is present. This bit MUST be
+ * set to 1 for control messages.
+ *
+ * The x bits are reserved for future extensions. All reserved bits MUST
+ * be set to 0 on outgoing messages and ignored on incoming messages.
+ *
+ * If the Sequence (S) bit is set to 1 the Ns and Nr fields are present.
+ * The S bit MUST be set to 1 for control messages.
+ *
+ * If the Offset (O) bit is 1, the Offset Size field is present. The O
+ * bit MUST be set to 0 for control messages.
+ *
+ * If the Priority (P) bit is 1, this data message should receive
+ * preferential treatment in its local queuing and transmission.
+ * The P bit MUST be set to 0 for control messages.
+ *
+ * Ver MUST be 2, indicating the version of the L2TP data message header.
+ *
+ * The Length field indicates the total length of the message in octets.
+ *
+ * Tunnel ID indicates the identifier for the control connection.
+ *
+ * Session ID indicates the identifier for a session within a tunnel.
+ *
+ * Ns indicates the sequence number for this data or control message.
+ *
+ * Nr indicates the sequence number expected in the next control message
+ * to be received.
+ *
+ * The Offset Size field, if present, specifies the number of octets
+ * past the L2TP header at which the payload data is expected to start.
+ * Actual data within the offset padding is undefined. If the offset
+ * field is present, the L2TP header ends after the last octet of the
+ * offset padding.
+ */
+
+#include <stdint.h>
+#include <rte_byteorder.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * L2TPv2 Common Header
+ */
+RTE_STD_C11
+struct rte_l2tpv2_common_hdr {
+	union {
+		/** header flags and protocol version */
+		rte_be16_t flags_version;
+		struct {
+#if RTE_BYTE_ORDER == RTE_LITTLE_ENDIAN
+			rte_be16_t t:1;		/**< message Type */
+			rte_be16_t l:1;		/**< length option bit */
+			rte_be16_t res1:2;	/**< reserved */
+			rte_be16_t s:1;		/**< ns/nr option bit */
+			rte_be16_t res2:1;	/**< reserved */
+			rte_be16_t o:1;		/**< offset option bit */
+			rte_be16_t p:1;		/**< priority option bit */
+			rte_be16_t res3:4;	/**< reserved */
+			rte_be16_t ver:4;	/**< protocol version */
+#elif RTE_BYTE_ORDER == RTE_BIG_ENDIAN
+			rte_be16_t ver:4;	/**< protocol version */
+			rte_be16_t res3:4;	/**< reserved */
+			rte_be16_t p:1;		/**< priority option bit */
+			rte_be16_t o:1;		/**< offset option bit */
+			rte_be16_t res2:1;	/**< reserved */
+			rte_be16_t s:1;		/**< ns/nr option bit */
+			rte_be16_t res1:2;	/**< reserved */
+			rte_be16_t l:1;		/**< length option bit */
+			rte_be16_t t:1;		/**< message Type */
+#endif
+		};
+	};
+};
+
+/**
+ * L2TPv2 message Header contains all options(length, ns, nr,
+ * offset size, offset padding).
+ */
+struct rte_l2tpv2_msg_with_all_options {
+	rte_be16_t length;		/**< length(16) */
+	rte_be16_t tunnel_id;		/**< tunnel ID(16) */
+	rte_be16_t session_id;		/**< session ID(16) */
+	rte_be16_t ns;			/**< Ns(16) */
+	rte_be16_t nr;			/**< Nr(16) */
+	rte_be16_t offset_size;		/**< offset size(16) */
+	uint8_t   *offset_padding;	/**< offset padding(variable length) */
+} __rte_packed;
+
+/**
+ * L2TPv2 message Header contains all options except length(ns, nr,
+ * offset size, offset padding).
+ */
+struct rte_l2tpv2_msg_without_length {
+	rte_be16_t tunnel_id;		/**< tunnel ID(16) */
+	rte_be16_t session_id;		/**< session ID(16) */
+	rte_be16_t ns;			/**< Ns(16) */
+	rte_be16_t nr;			/**< Nr(16) */
+	rte_be16_t offset_size;		/**< offset size(16) */
+	uint8_t   *offset_padding;	/**< offset padding(variable length) */
+} __rte_packed;
+
+/**
+ * L2TPv2 message Header contains all options except ns_nr(length,
+ * offset size, offset padding).
+ * Ns and Nr MUST be toghter.
+ */
+struct rte_l2tpv2_msg_without_ns_nr {
+	rte_be16_t length;		/**< length(16) */
+	rte_be16_t tunnel_id;		/**< tunnel ID(16) */
+	rte_be16_t session_id;		/**< session ID(16) */
+	rte_be16_t offset_size;		/**< offset size(16) */
+	uint8_t   *offset_padding;	/**< offset padding(variable length) */
+};
+
+/**
+ * L2TPv2 message Header contains all options except ns_nr(length, ns, nr).
+ * offset size and offset padding MUST be toghter.
+ */
+struct rte_l2tpv2_msg_without_offset {
+	rte_be16_t length;		/**< length(16) */
+	rte_be16_t tunnel_id;		/**< tunnel ID(16) */
+	rte_be16_t session_id;		/**< session ID(16) */
+	rte_be16_t ns;			/**< Ns(16) */
+	rte_be16_t nr;			/**< Nr(16) */
+};
+
+/**
+ * L2TPv2 message Header contains options offset size and offset padding.
+ */
+struct rte_l2tpv2_msg_with_offset {
+	rte_be16_t tunnel_id;		/**< tunnel ID(16) */
+	rte_be16_t session_id;		/**< session ID(16) */
+	rte_be16_t offset_size;		/**< offset size(16) */
+	uint8_t   *offset_padding;	/**< offset padding(variable length) */
+} __rte_packed;
+
+/**
+ * L2TPv2 message Header contains options ns and nr.
+ */
+struct rte_l2tpv2_msg_with_ns_nr {
+	rte_be16_t tunnel_id;		/**< tunnel ID(16) */
+	rte_be16_t session_id;		/**< session ID(16) */
+	rte_be16_t ns;			/**< Ns(16) */
+	rte_be16_t nr;			/**< Nr(16) */
+};
+
+/**
+ * L2TPv2 message Header contains option length.
+ */
+struct rte_l2tpv2_msg_with_length {
+	rte_be16_t length;		/**< length(16) */
+	rte_be16_t tunnel_id;		/**< tunnel ID(16) */
+	rte_be16_t session_id;		/**< session ID(16) */
+};
+
+/**
+ * L2TPv2 message Header without all options.
+ */
+struct rte_l2tpv2_msg_without_all_options {
+	rte_be16_t tunnel_id;		/**< tunnel ID(16) */
+	rte_be16_t session_id;		/**< session ID(16) */
+};
+
+/**
+ * L2TPv2 Combined Message Header Format: Common Header + Options
+ */
+RTE_STD_C11
+struct rte_l2tpv2_combined_msg_hdr {
+	struct rte_l2tpv2_common_hdr common; /**< common header */
+	union {
+		/** header with all options */
+		struct rte_l2tpv2_msg_with_all_options type0;
+		/** header with all options except length */
+		struct rte_l2tpv2_msg_without_length type1;
+		/** header with all options except ns/nr */
+		struct rte_l2tpv2_msg_without_ns_nr type2;
+		/** header with all options except offset */
+		struct rte_l2tpv2_msg_without_offset type3;
+		/** header with offset options */
+		struct rte_l2tpv2_msg_with_offset type4;
+		/** header with ns/nr options */
+		struct rte_l2tpv2_msg_with_ns_nr type5;
+		/** header with length option */
+		struct rte_l2tpv2_msg_with_length type6;
+		/** header without all options */
+		struct rte_l2tpv2_msg_without_all_options type7;
+	};
+} __rte_packed;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RTE_L2TPV2_H_ */
diff --git a/lib/net/rte_ppp.h b/lib/net/rte_ppp.h
new file mode 100644
index 0000000000..7b86ac4363
--- /dev/null
+++ b/lib/net/rte_ppp.h
@@ -0,0 +1,34 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2021 Intel Corporation.
+ */
+
+#ifndef _RTE_PPP_H_
+#define _RTE_PPP_H_
+
+/**
+ * @file
+ *
+ * PPP headers definition.
+ */
+
+#include <stdint.h>
+#include <rte_byteorder.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * PPP Header
+ */
+struct rte_ppp_hdr {
+	uint8_t addr; /**< PPP address(8) */
+	uint8_t ctrl; /**< PPP control(8) */
+	rte_be16_t proto_id; /**< PPP protocol identifier(16) */
+} __rte_packed;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RTE_PPP_H_ */
-- 
2.25.1


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

* [dpdk-dev] [PATCH v9 2/3] net/iavf: support PPPoL2TPv2oUDP RSS Hash
  2021-10-21 10:49               ` [dpdk-dev] [PATCH v9 0/3] support PPPoL2TPv2oUDP RSS Hash Jie Wang
  2021-10-21 10:49                 ` [dpdk-dev] [PATCH v9 1/3] ethdev: support L2TPv2 and PPP procotol Jie Wang
@ 2021-10-21 10:49                 ` Jie Wang
  2021-10-21 10:49                 ` [dpdk-dev] [PATCH v9 3/3] app/testpmd: support L2TPv2 and PPP protocol pattern Jie Wang
  2021-10-21 12:17                 ` [dpdk-dev] [PATCH v9 0/3] support PPPoL2TPv2oUDP RSS Hash Ferruh Yigit
  3 siblings, 0 replies; 71+ messages in thread
From: Jie Wang @ 2021-10-21 10:49 UTC (permalink / raw)
  To: dev
  Cc: orika, ferruh.yigit, thomas, andrew.rybchenko, xiaoyun.li,
	stevex.yang, jingjing.wu, beilei.xing, wenjun1.wu, qi.z.zhang,
	Jie Wang

Add support for PPP over L2TPv2 over UDP protocol RSS Hash based
on inner IP src/dst address and TCP/UDP src/dst port.

Patterns are listed below:
eth/ipv4(6)/udp/l2tpv2/ppp/ipv4(6)
eth/ipv4(6)/udp/l2tpv2/ppp/ipv4(6)/udp
eth/ipv4(6)/udp/l2tpv2/ppp/ipv4(6)/tcp

Signed-off-by: Wenjun Wu <wenjun1.wu@intel.com>
Signed-off-by: Jie Wang <jie1x.wang@intel.com>
Acked-by: Beilei Xing <beilei.xing@intel.com>
---
 doc/guides/nics/features/iavf.ini      |   2 +
 doc/guides/rel_notes/release_21_11.rst |   1 +
 drivers/net/iavf/iavf_generic_flow.c   | 131 +++++++++++++++++++++++++
 drivers/net/iavf/iavf_generic_flow.h   |  15 +++
 drivers/net/iavf/iavf_hash.c           | 108 +++++++++++++++++++-
 5 files changed, 255 insertions(+), 2 deletions(-)

diff --git a/doc/guides/nics/features/iavf.ini b/doc/guides/nics/features/iavf.ini
index d00ca934c3..a916275b88 100644
--- a/doc/guides/nics/features/iavf.ini
+++ b/doc/guides/nics/features/iavf.ini
@@ -50,8 +50,10 @@ icmp6                = Y
 ipv4                 = Y
 ipv6                 = Y
 ipv6_frag_ext        = Y
+l2tpv2               = Y
 l2tpv3oip            = Y
 pfcp                 = Y
+ppp                  = Y
 sctp                 = Y
 tcp                  = Y
 udp                  = Y
diff --git a/doc/guides/rel_notes/release_21_11.rst b/doc/guides/rel_notes/release_21_11.rst
index 283770131c..bd0eacc0c5 100644
--- a/doc/guides/rel_notes/release_21_11.rst
+++ b/doc/guides/rel_notes/release_21_11.rst
@@ -132,6 +132,7 @@ New Features
 
   * Added Intel iavf support on Windows.
   * Added IPv4 and L4 (TCP/UDP/SCTP) checksum hash support in RSS flow.
+  * Added PPPoL2TPv2oUDP RSS hash based on inner IP address and TCP/UDP port.
 
 * **Updated Intel ice driver.**
 
diff --git a/drivers/net/iavf/iavf_generic_flow.c b/drivers/net/iavf/iavf_generic_flow.c
index b86d99e57d..364904fa02 100644
--- a/drivers/net/iavf/iavf_generic_flow.c
+++ b/drivers/net/iavf/iavf_generic_flow.c
@@ -1611,6 +1611,137 @@ enum rte_flow_item_type iavf_pattern_eth_ipv6_gre_ipv6_udp[] = {
 	RTE_FLOW_ITEM_TYPE_END,
 };
 
+/* PPPoL2TPv2oUDP */
+enum rte_flow_item_type iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv4[] = {
+	RTE_FLOW_ITEM_TYPE_ETH,
+	RTE_FLOW_ITEM_TYPE_IPV4,
+	RTE_FLOW_ITEM_TYPE_UDP,
+	RTE_FLOW_ITEM_TYPE_L2TPV2,
+	RTE_FLOW_ITEM_TYPE_PPP,
+	RTE_FLOW_ITEM_TYPE_IPV4,
+	RTE_FLOW_ITEM_TYPE_END,
+};
+
+enum rte_flow_item_type iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv6[] = {
+	RTE_FLOW_ITEM_TYPE_ETH,
+	RTE_FLOW_ITEM_TYPE_IPV4,
+	RTE_FLOW_ITEM_TYPE_UDP,
+	RTE_FLOW_ITEM_TYPE_L2TPV2,
+	RTE_FLOW_ITEM_TYPE_PPP,
+	RTE_FLOW_ITEM_TYPE_IPV6,
+	RTE_FLOW_ITEM_TYPE_END,
+};
+
+enum rte_flow_item_type iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv4_udp[] = {
+	RTE_FLOW_ITEM_TYPE_ETH,
+	RTE_FLOW_ITEM_TYPE_IPV4,
+	RTE_FLOW_ITEM_TYPE_UDP,
+	RTE_FLOW_ITEM_TYPE_L2TPV2,
+	RTE_FLOW_ITEM_TYPE_PPP,
+	RTE_FLOW_ITEM_TYPE_IPV4,
+	RTE_FLOW_ITEM_TYPE_UDP,
+	RTE_FLOW_ITEM_TYPE_END,
+};
+
+enum rte_flow_item_type iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv4_tcp[] = {
+	RTE_FLOW_ITEM_TYPE_ETH,
+	RTE_FLOW_ITEM_TYPE_IPV4,
+	RTE_FLOW_ITEM_TYPE_UDP,
+	RTE_FLOW_ITEM_TYPE_L2TPV2,
+	RTE_FLOW_ITEM_TYPE_PPP,
+	RTE_FLOW_ITEM_TYPE_IPV4,
+	RTE_FLOW_ITEM_TYPE_TCP,
+	RTE_FLOW_ITEM_TYPE_END,
+};
+
+enum rte_flow_item_type iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv6_udp[] = {
+	RTE_FLOW_ITEM_TYPE_ETH,
+	RTE_FLOW_ITEM_TYPE_IPV4,
+	RTE_FLOW_ITEM_TYPE_UDP,
+	RTE_FLOW_ITEM_TYPE_L2TPV2,
+	RTE_FLOW_ITEM_TYPE_PPP,
+	RTE_FLOW_ITEM_TYPE_IPV6,
+	RTE_FLOW_ITEM_TYPE_UDP,
+	RTE_FLOW_ITEM_TYPE_END,
+};
+
+enum rte_flow_item_type iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv6_tcp[] = {
+	RTE_FLOW_ITEM_TYPE_ETH,
+	RTE_FLOW_ITEM_TYPE_IPV4,
+	RTE_FLOW_ITEM_TYPE_UDP,
+	RTE_FLOW_ITEM_TYPE_L2TPV2,
+	RTE_FLOW_ITEM_TYPE_PPP,
+	RTE_FLOW_ITEM_TYPE_IPV6,
+	RTE_FLOW_ITEM_TYPE_TCP,
+	RTE_FLOW_ITEM_TYPE_END,
+};
+
+enum rte_flow_item_type iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv4[] = {
+	RTE_FLOW_ITEM_TYPE_ETH,
+	RTE_FLOW_ITEM_TYPE_IPV6,
+	RTE_FLOW_ITEM_TYPE_UDP,
+	RTE_FLOW_ITEM_TYPE_L2TPV2,
+	RTE_FLOW_ITEM_TYPE_PPP,
+	RTE_FLOW_ITEM_TYPE_IPV4,
+	RTE_FLOW_ITEM_TYPE_END,
+};
+
+enum rte_flow_item_type iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv6[] = {
+	RTE_FLOW_ITEM_TYPE_ETH,
+	RTE_FLOW_ITEM_TYPE_IPV6,
+	RTE_FLOW_ITEM_TYPE_UDP,
+	RTE_FLOW_ITEM_TYPE_L2TPV2,
+	RTE_FLOW_ITEM_TYPE_PPP,
+	RTE_FLOW_ITEM_TYPE_IPV6,
+	RTE_FLOW_ITEM_TYPE_END,
+};
+
+enum rte_flow_item_type iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv4_udp[] = {
+	RTE_FLOW_ITEM_TYPE_ETH,
+	RTE_FLOW_ITEM_TYPE_IPV6,
+	RTE_FLOW_ITEM_TYPE_UDP,
+	RTE_FLOW_ITEM_TYPE_L2TPV2,
+	RTE_FLOW_ITEM_TYPE_PPP,
+	RTE_FLOW_ITEM_TYPE_IPV4,
+	RTE_FLOW_ITEM_TYPE_UDP,
+	RTE_FLOW_ITEM_TYPE_END,
+};
+
+enum rte_flow_item_type iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv4_tcp[] = {
+	RTE_FLOW_ITEM_TYPE_ETH,
+	RTE_FLOW_ITEM_TYPE_IPV6,
+	RTE_FLOW_ITEM_TYPE_UDP,
+	RTE_FLOW_ITEM_TYPE_L2TPV2,
+	RTE_FLOW_ITEM_TYPE_PPP,
+	RTE_FLOW_ITEM_TYPE_IPV4,
+	RTE_FLOW_ITEM_TYPE_TCP,
+	RTE_FLOW_ITEM_TYPE_END,
+};
+
+enum rte_flow_item_type iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv6_udp[] = {
+	RTE_FLOW_ITEM_TYPE_ETH,
+	RTE_FLOW_ITEM_TYPE_IPV6,
+	RTE_FLOW_ITEM_TYPE_UDP,
+	RTE_FLOW_ITEM_TYPE_L2TPV2,
+	RTE_FLOW_ITEM_TYPE_PPP,
+	RTE_FLOW_ITEM_TYPE_IPV6,
+	RTE_FLOW_ITEM_TYPE_UDP,
+	RTE_FLOW_ITEM_TYPE_END,
+};
+
+enum rte_flow_item_type iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv6_tcp[] = {
+	RTE_FLOW_ITEM_TYPE_ETH,
+	RTE_FLOW_ITEM_TYPE_IPV6,
+	RTE_FLOW_ITEM_TYPE_UDP,
+	RTE_FLOW_ITEM_TYPE_L2TPV2,
+	RTE_FLOW_ITEM_TYPE_PPP,
+	RTE_FLOW_ITEM_TYPE_IPV6,
+	RTE_FLOW_ITEM_TYPE_TCP,
+	RTE_FLOW_ITEM_TYPE_END,
+};
+
+
+
 typedef struct iavf_flow_engine * (*parse_engine_t)(struct iavf_adapter *ad,
 		struct rte_flow *flow,
 		struct iavf_parser_list *parser_list,
diff --git a/drivers/net/iavf/iavf_generic_flow.h b/drivers/net/iavf/iavf_generic_flow.h
index 4794d1fb80..f2b54e1944 100644
--- a/drivers/net/iavf/iavf_generic_flow.h
+++ b/drivers/net/iavf/iavf_generic_flow.h
@@ -410,6 +410,21 @@ extern enum rte_flow_item_type iavf_pattern_eth_ipv6_gre_ipv6_tcp[];
 extern enum rte_flow_item_type iavf_pattern_eth_ipv6_gre_ipv4_udp[];
 extern enum rte_flow_item_type iavf_pattern_eth_ipv6_gre_ipv6_udp[];
 
+/* PPPoL2TPv2oUDP */
+extern enum rte_flow_item_type iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv4[];
+extern enum rte_flow_item_type iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv6[];
+extern enum rte_flow_item_type iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv4_udp[];
+extern enum rte_flow_item_type iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv4_tcp[];
+extern enum rte_flow_item_type iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv6_udp[];
+extern enum rte_flow_item_type iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv6_tcp[];
+extern enum rte_flow_item_type iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv4[];
+extern enum rte_flow_item_type iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv6[];
+extern enum rte_flow_item_type iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv4_udp[];
+extern enum rte_flow_item_type iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv4_tcp[];
+extern enum rte_flow_item_type iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv6_udp[];
+extern enum rte_flow_item_type iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv6_tcp[];
+
+
 extern const struct rte_flow_ops iavf_flow_ops;
 
 /* pattern structure */
diff --git a/drivers/net/iavf/iavf_hash.c b/drivers/net/iavf/iavf_hash.c
index 1f2d3772d1..01724cd569 100644
--- a/drivers/net/iavf/iavf_hash.c
+++ b/drivers/net/iavf/iavf_hash.c
@@ -34,6 +34,8 @@
 /* the second IP header of GTPoGRE */
 #define IAVF_PHINT_MID_IPV4			BIT_ULL(7)
 #define IAVF_PHINT_MID_IPV6			BIT_ULL(8)
+/* L2TPv2 */
+#define IAVF_PHINT_L2TPV2			BIT_ULL(9)
 
 #define IAVF_PHINT_GTPU_MSK	(IAVF_PHINT_GTPU	| \
 				 IAVF_PHINT_GTPU_EH	| \
@@ -164,6 +166,12 @@ iavf_hash_parse_pattern_action(struct iavf_adapter *ad,
 	VIRTCHNL_PROTO_HDR_ECPRI, \
 	FIELD_SELECTOR(VIRTCHNL_PROTO_HDR_ECPRI_PC_RTC_ID), {BUFF_NOUSED} }
 
+#define proto_hdr_l2tpv2 { \
+	VIRTCHNL_PROTO_HDR_L2TPV2, 0, {BUFF_NOUSED} }
+
+#define proto_hdr_ppp { \
+	VIRTCHNL_PROTO_HDR_PPP, 0, {BUFF_NOUSED} }
+
 #define TUNNEL_LEVEL_OUTER		0
 #define TUNNEL_LEVEL_INNER		1
 
@@ -338,6 +346,52 @@ struct virtchnl_proto_hdrs ipv4_ecpri_tmplt = {
 	TUNNEL_LEVEL_OUTER, 3, {proto_hdr_ipv4, proto_hdr_udp, proto_hdr_ecpri}
 };
 
+struct virtchnl_proto_hdrs udp_l2tpv2_ppp_ipv4_tmplt = {
+	TUNNEL_LEVEL_INNER, 3,
+	{proto_hdr_l2tpv2,
+	 proto_hdr_ppp,
+	 proto_hdr_ipv4}
+};
+
+struct virtchnl_proto_hdrs udp_l2tpv2_ppp_ipv6_tmplt = {
+	TUNNEL_LEVEL_INNER, 3,
+	{proto_hdr_l2tpv2,
+	 proto_hdr_ppp,
+	 proto_hdr_ipv6}
+};
+
+struct virtchnl_proto_hdrs udp_l2tpv2_ppp_ipv4_udp_tmplt = {
+	TUNNEL_LEVEL_INNER, 4,
+	{proto_hdr_l2tpv2,
+	 proto_hdr_ppp,
+	 proto_hdr_ipv4_with_prot,
+	 proto_hdr_udp}
+};
+
+struct virtchnl_proto_hdrs udp_l2tpv2_ppp_ipv4_tcp_tmplt = {
+	TUNNEL_LEVEL_INNER, 4,
+	{proto_hdr_l2tpv2,
+	 proto_hdr_ppp,
+	 proto_hdr_ipv4_with_prot,
+	 proto_hdr_tcp}
+};
+
+struct virtchnl_proto_hdrs udp_l2tpv2_ppp_ipv6_udp_tmplt = {
+	TUNNEL_LEVEL_INNER, 4,
+	{proto_hdr_l2tpv2,
+	 proto_hdr_ppp,
+	 proto_hdr_ipv6_with_prot,
+	 proto_hdr_udp}
+};
+
+struct virtchnl_proto_hdrs udp_l2tpv2_ppp_ipv6_tcp_tmplt = {
+	TUNNEL_LEVEL_INNER, 4,
+	{proto_hdr_l2tpv2,
+	 proto_hdr_ppp,
+	 proto_hdr_ipv6_with_prot,
+	 proto_hdr_tcp}
+};
+
 /* rss type super set */
 
 /* IPv4 outer */
@@ -493,6 +547,13 @@ static struct iavf_pattern_match_item iavf_hash_pattern_list[] = {
 	{iavf_pattern_eth_ipv6_gre_ipv4_tcp,	IAVF_RSS_TYPE_INNER_IPV4_TCP, &inner_ipv4_tcp_tmplt},
 	{iavf_pattern_eth_ipv4_gre_ipv4_udp,	IAVF_RSS_TYPE_INNER_IPV4_UDP, &inner_ipv4_udp_tmplt},
 	{iavf_pattern_eth_ipv6_gre_ipv4_udp,	IAVF_RSS_TYPE_INNER_IPV4_UDP, &inner_ipv4_udp_tmplt},
+	{iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv4,	IAVF_RSS_TYPE_INNER_IPV4,	&udp_l2tpv2_ppp_ipv4_tmplt},
+	{iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv4_udp,	IAVF_RSS_TYPE_INNER_IPV4_UDP,	&udp_l2tpv2_ppp_ipv4_udp_tmplt},
+	{iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv4_tcp,	IAVF_RSS_TYPE_INNER_IPV4_TCP,	&udp_l2tpv2_ppp_ipv4_tcp_tmplt},
+	{iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv4,	IAVF_RSS_TYPE_INNER_IPV4,	&udp_l2tpv2_ppp_ipv4_tmplt},
+	{iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv4_udp,	IAVF_RSS_TYPE_INNER_IPV4_UDP,	&udp_l2tpv2_ppp_ipv4_udp_tmplt},
+	{iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv4_tcp,	IAVF_RSS_TYPE_INNER_IPV4_TCP,	&udp_l2tpv2_ppp_ipv4_tcp_tmplt},
+
 	/* IPv6 */
 	{iavf_pattern_eth_ipv6,				IAVF_RSS_TYPE_OUTER_IPV6,	&outer_ipv6_tmplt},
 	{iavf_pattern_eth_ipv6_frag_ext,		IAVF_RSS_TYPE_OUTER_IPV6_FRAG,	&outer_ipv6_frag_tmplt},
@@ -553,6 +614,13 @@ static struct iavf_pattern_match_item iavf_hash_pattern_list[] = {
 	{iavf_pattern_eth_ipv6_gre_ipv6_tcp,	IAVF_RSS_TYPE_INNER_IPV6_TCP, &inner_ipv6_tcp_tmplt},
 	{iavf_pattern_eth_ipv4_gre_ipv6_udp,	IAVF_RSS_TYPE_INNER_IPV6_UDP, &inner_ipv6_udp_tmplt},
 	{iavf_pattern_eth_ipv6_gre_ipv6_udp,	IAVF_RSS_TYPE_INNER_IPV6_UDP, &inner_ipv6_udp_tmplt},
+	{iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv6,	IAVF_RSS_TYPE_INNER_IPV6,	&udp_l2tpv2_ppp_ipv6_tmplt},
+	{iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv6_udp,	IAVF_RSS_TYPE_INNER_IPV6_UDP,	&udp_l2tpv2_ppp_ipv6_udp_tmplt},
+	{iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv6_tcp,	IAVF_RSS_TYPE_INNER_IPV6_TCP,	&udp_l2tpv2_ppp_ipv6_tcp_tmplt},
+	{iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv6,	IAVF_RSS_TYPE_INNER_IPV6,	&udp_l2tpv2_ppp_ipv6_tmplt},
+	{iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv6_udp,	IAVF_RSS_TYPE_INNER_IPV6_UDP,	&udp_l2tpv2_ppp_ipv6_udp_tmplt},
+	{iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv6_tcp,	IAVF_RSS_TYPE_INNER_IPV6_TCP,	&udp_l2tpv2_ppp_ipv6_tcp_tmplt},
+
 };
 
 static struct iavf_flow_engine iavf_hash_engine = {
@@ -687,13 +755,17 @@ iavf_hash_parse_pattern(const struct rte_flow_item pattern[], uint64_t *phint,
 
 		switch (item->type) {
 		case RTE_FLOW_ITEM_TYPE_IPV4:
-			if (!(*phint & IAVF_PHINT_GTPU_MSK) && !(*phint & IAVF_PHINT_GRE))
+			if (!(*phint & IAVF_PHINT_GTPU_MSK) &&
+			    !(*phint & IAVF_PHINT_GRE) &&
+			    !(*phint & IAVF_PHINT_L2TPV2))
 				*phint |= IAVF_PHINT_OUTER_IPV4;
 			if ((*phint & IAVF_PHINT_GRE) && !(*phint & IAVF_PHINT_GTPU_MSK))
 				*phint |= IAVF_PHINT_MID_IPV4;
 			break;
 		case RTE_FLOW_ITEM_TYPE_IPV6:
-			if (!(*phint & IAVF_PHINT_GTPU_MSK) && !(*phint & IAVF_PHINT_GRE))
+			if (!(*phint & IAVF_PHINT_GTPU_MSK) &&
+			    !(*phint & IAVF_PHINT_GRE) &&
+			    !(*phint & IAVF_PHINT_L2TPV2))
 				*phint |= IAVF_PHINT_OUTER_IPV6;
 			if ((*phint & IAVF_PHINT_GRE) && !(*phint & IAVF_PHINT_GTPU_MSK))
 				*phint |= IAVF_PHINT_MID_IPV6;
@@ -728,6 +800,10 @@ iavf_hash_parse_pattern(const struct rte_flow_item pattern[], uint64_t *phint,
 			break;
 		case RTE_FLOW_ITEM_TYPE_GRE:
 			*phint |= IAVF_PHINT_GRE;
+			break;
+		case RTE_FLOW_ITEM_TYPE_L2TPV2:
+			*phint |= IAVF_PHINT_L2TPV2;
+			break;
 		default:
 			break;
 		}
@@ -1050,12 +1126,40 @@ iavf_refine_proto_hdrs_by_pattern(struct virtchnl_proto_hdrs *proto_hdrs,
 	proto_hdrs->tunnel_level = tun_lvl;
 }
 
+static void
+iavf_refine_proto_hdrs_l2tpv2(struct virtchnl_proto_hdrs *proto_hdrs,
+			      uint64_t phint)
+{
+	struct virtchnl_proto_hdr *hdr1;
+	int i;
+
+	if (!(phint & IAVF_PHINT_L2TPV2))
+		return;
+
+	if (proto_hdrs->tunnel_level == TUNNEL_LEVEL_INNER) {
+		/* shift headers layer */
+		for (i = proto_hdrs->count - 1 + 1; i > 0; i--)
+			proto_hdrs->proto_hdr[i] = proto_hdrs->proto_hdr[i - 1];
+
+		/* adding outer ip header at layer 0 */
+		hdr1 = &proto_hdrs->proto_hdr[0];
+		hdr1->field_selector = 0;
+		proto_hdrs->count++;
+		proto_hdrs->tunnel_level = TUNNEL_LEVEL_OUTER;
+		if (phint & IAVF_PHINT_OUTER_IPV4)
+			VIRTCHNL_SET_PROTO_HDR_TYPE(hdr1, IPV4);
+		else if (phint & IAVF_PHINT_OUTER_IPV6)
+			VIRTCHNL_SET_PROTO_HDR_TYPE(hdr1, IPV6);
+	}
+}
+
 static void iavf_refine_proto_hdrs(struct virtchnl_proto_hdrs *proto_hdrs,
 				   uint64_t rss_type, uint64_t phint)
 {
 	iavf_refine_proto_hdrs_l234(proto_hdrs, rss_type);
 	iavf_refine_proto_hdrs_by_pattern(proto_hdrs, phint);
 	iavf_refine_proto_hdrs_gtpu(proto_hdrs, rss_type);
+	iavf_refine_proto_hdrs_l2tpv2(proto_hdrs, phint);
 }
 
 static uint64_t invalid_rss_comb[] = {
-- 
2.25.1


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

* [dpdk-dev] [PATCH v9 3/3] app/testpmd: support L2TPv2 and PPP protocol pattern
  2021-10-21 10:49               ` [dpdk-dev] [PATCH v9 0/3] support PPPoL2TPv2oUDP RSS Hash Jie Wang
  2021-10-21 10:49                 ` [dpdk-dev] [PATCH v9 1/3] ethdev: support L2TPv2 and PPP procotol Jie Wang
  2021-10-21 10:49                 ` [dpdk-dev] [PATCH v9 2/3] net/iavf: support PPPoL2TPv2oUDP RSS Hash Jie Wang
@ 2021-10-21 10:49                 ` Jie Wang
  2021-10-21 12:17                 ` [dpdk-dev] [PATCH v9 0/3] support PPPoL2TPv2oUDP RSS Hash Ferruh Yigit
  3 siblings, 0 replies; 71+ messages in thread
From: Jie Wang @ 2021-10-21 10:49 UTC (permalink / raw)
  To: dev
  Cc: orika, ferruh.yigit, thomas, andrew.rybchenko, xiaoyun.li,
	stevex.yang, jingjing.wu, beilei.xing, wenjun1.wu, qi.z.zhang,
	Jie Wang

Add support for test-pmd to parse protocol pattern L2TPv2 and PPP.

Signed-off-by: Wenjun Wu <wenjun1.wu@intel.com>
Signed-off-by: Jie Wang <jie1x.wang@intel.com>
---
 app/test-pmd/cmdline_flow.c                 | 251 ++++++++++++++++++++
 doc/guides/testpmd_app_ug/testpmd_funcs.rst |  28 +++
 2 files changed, 279 insertions(+)

diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
index 5437975837..d8218771fb 100644
--- a/app/test-pmd/cmdline_flow.c
+++ b/app/test-pmd/cmdline_flow.c
@@ -321,6 +321,23 @@ enum index {
 	ITEM_FLEX,
 	ITEM_FLEX_ITEM_HANDLE,
 	ITEM_FLEX_PATTERN_HANDLE,
+	ITEM_L2TPV2,
+	ITEM_L2TPV2_COMMON,
+	ITEM_L2TPV2_COMMON_TYPE,
+	ITEM_L2TPV2_COMMON_TYPE_DATA_L,
+	ITEM_L2TPV2_COMMON_TYPE_CTRL,
+	ITEM_L2TPV2_MSG_DATA_L_LENGTH,
+	ITEM_L2TPV2_MSG_DATA_L_TUNNEL_ID,
+	ITEM_L2TPV2_MSG_DATA_L_SESSION_ID,
+	ITEM_L2TPV2_MSG_CTRL_LENGTH,
+	ITEM_L2TPV2_MSG_CTRL_TUNNEL_ID,
+	ITEM_L2TPV2_MSG_CTRL_SESSION_ID,
+	ITEM_L2TPV2_MSG_CTRL_NS,
+	ITEM_L2TPV2_MSG_CTRL_NR,
+	ITEM_PPP,
+	ITEM_PPP_ADDR,
+	ITEM_PPP_CTRL,
+	ITEM_PPP_PROTO_ID,
 
 	/* Validate/create actions. */
 	ACTIONS,
@@ -1042,6 +1059,8 @@ static const enum index next_item[] = {
 	ITEM_PORT_REPRESENTOR,
 	ITEM_REPRESENTED_PORT,
 	ITEM_FLEX,
+	ITEM_L2TPV2,
+	ITEM_PPP,
 	END_SET,
 	ZERO,
 };
@@ -1429,6 +1448,31 @@ static const enum index item_flex[] = {
 	ZERO,
 };
 
+static const enum index item_l2tpv2[] = {
+	ITEM_L2TPV2_COMMON,
+	ITEM_NEXT,
+	ZERO,
+};
+
+static const enum index item_l2tpv2_common[] = {
+	ITEM_L2TPV2_COMMON_TYPE,
+	ZERO,
+};
+
+static const enum index item_l2tpv2_common_type[] = {
+	ITEM_L2TPV2_COMMON_TYPE_DATA_L,
+	ITEM_L2TPV2_COMMON_TYPE_CTRL,
+	ZERO,
+};
+
+static const enum index item_ppp[] = {
+	ITEM_PPP_ADDR,
+	ITEM_PPP_CTRL,
+	ITEM_PPP_PROTO_ID,
+	ITEM_NEXT,
+	ZERO,
+};
+
 static const enum index next_action[] = {
 	ACTION_END,
 	ACTION_VOID,
@@ -1815,6 +1859,9 @@ static int parse_vc_conf(struct context *, const struct token *,
 static int parse_vc_item_ecpri_type(struct context *, const struct token *,
 				    const char *, unsigned int,
 				    void *, unsigned int);
+static int parse_vc_item_l2tpv2_type(struct context *, const struct token *,
+				    const char *, unsigned int,
+				    void *, unsigned int);
 static int parse_vc_action_meter_color_type(struct context *,
 					const struct token *,
 					const char *, unsigned int, void *,
@@ -3789,6 +3836,153 @@ static const struct token token_list[] = {
 			     NEXT_ENTRY(ITEM_PARAM_IS)),
 		.args = ARGS(ARGS_ENTRY(struct rte_flow_item_flex, pattern)),
 	},
+	[ITEM_L2TPV2] = {
+		.name = "l2tpv2",
+		.help = "match L2TPv2 header",
+		.priv = PRIV_ITEM(L2TPV2, sizeof(struct rte_flow_item_l2tpv2)),
+		.next = NEXT(item_l2tpv2),
+		.call = parse_vc,
+	},
+	[ITEM_L2TPV2_COMMON] = {
+		.name = "common",
+		.help = "L2TPv2 common header",
+		.next = NEXT(item_l2tpv2_common),
+	},
+	[ITEM_L2TPV2_COMMON_TYPE] = {
+		.name = "type",
+		.help = "type of common header",
+		.next = NEXT(item_l2tpv2_common_type),
+		.args = ARGS(ARG_ENTRY_HTON(struct rte_flow_item_l2tpv2)),
+	},
+	[ITEM_L2TPV2_COMMON_TYPE_DATA_L] = {
+		.name = "data_l",
+		.help = "Type #6: data message with length option",
+		.next = NEXT(NEXT_ENTRY(ITEM_L2TPV2_MSG_DATA_L_LENGTH,
+					ITEM_L2TPV2_MSG_DATA_L_TUNNEL_ID,
+					ITEM_L2TPV2_MSG_DATA_L_SESSION_ID,
+					ITEM_NEXT)),
+		.call = parse_vc_item_l2tpv2_type,
+	},
+	[ITEM_L2TPV2_MSG_DATA_L_LENGTH] = {
+		.name = "length",
+		.help = "message length",
+		.next = NEXT(NEXT_ENTRY(ITEM_L2TPV2_MSG_DATA_L_LENGTH,
+					ITEM_L2TPV2_COMMON, ITEM_NEXT),
+			     NEXT_ENTRY(COMMON_UNSIGNED),
+			     item_param),
+		.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2,
+					     hdr.type6.length)),
+	},
+	[ITEM_L2TPV2_MSG_DATA_L_TUNNEL_ID] = {
+		.name = "tunnel_id",
+		.help = "tunnel identifier",
+		.next = NEXT(NEXT_ENTRY(ITEM_L2TPV2_MSG_DATA_L_TUNNEL_ID,
+					ITEM_L2TPV2_COMMON, ITEM_NEXT),
+			     NEXT_ENTRY(COMMON_UNSIGNED),
+			     item_param),
+		.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2,
+					     hdr.type6.tunnel_id)),
+	},
+	[ITEM_L2TPV2_MSG_DATA_L_SESSION_ID] = {
+		.name = "session_id",
+		.help = "session identifier",
+		.next = NEXT(NEXT_ENTRY(ITEM_L2TPV2_MSG_DATA_L_SESSION_ID,
+					ITEM_L2TPV2_COMMON, ITEM_NEXT),
+			     NEXT_ENTRY(COMMON_UNSIGNED),
+			     item_param),
+		.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2,
+					     hdr.type6.session_id)),
+	},
+	[ITEM_L2TPV2_COMMON_TYPE_CTRL] = {
+		.name = "control",
+		.help = "Type #3: conrtol message contains length, ns, nr options",
+		.next = NEXT(NEXT_ENTRY(ITEM_L2TPV2_MSG_CTRL_LENGTH,
+					ITEM_L2TPV2_MSG_CTRL_TUNNEL_ID,
+					ITEM_L2TPV2_MSG_CTRL_SESSION_ID,
+					ITEM_L2TPV2_MSG_CTRL_NS,
+					ITEM_L2TPV2_MSG_CTRL_NR,
+					ITEM_NEXT)),
+		.call = parse_vc_item_l2tpv2_type,
+	},
+	[ITEM_L2TPV2_MSG_CTRL_LENGTH] = {
+		.name = "length",
+		.help = "message length",
+		.next = NEXT(NEXT_ENTRY(ITEM_L2TPV2_MSG_CTRL_LENGTH,
+					ITEM_L2TPV2_COMMON, ITEM_NEXT),
+			     NEXT_ENTRY(COMMON_UNSIGNED),
+			     item_param),
+		.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2,
+					     hdr.type3.length)),
+	},
+	[ITEM_L2TPV2_MSG_CTRL_TUNNEL_ID] = {
+		.name = "tunnel_id",
+		.help = "tunnel identifier",
+		.next = NEXT(NEXT_ENTRY(ITEM_L2TPV2_MSG_CTRL_TUNNEL_ID,
+					ITEM_L2TPV2_COMMON, ITEM_NEXT),
+			     NEXT_ENTRY(COMMON_UNSIGNED),
+			     item_param),
+		.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2,
+					     hdr.type3.tunnel_id)),
+	},
+	[ITEM_L2TPV2_MSG_CTRL_SESSION_ID] = {
+		.name = "session_id",
+		.help = "session identifier",
+		.next = NEXT(NEXT_ENTRY(ITEM_L2TPV2_MSG_CTRL_SESSION_ID,
+					ITEM_L2TPV2_COMMON, ITEM_NEXT),
+			     NEXT_ENTRY(COMMON_UNSIGNED),
+			     item_param),
+		.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2,
+					     hdr.type3.session_id)),
+	},
+	[ITEM_L2TPV2_MSG_CTRL_NS] = {
+		.name = "ns",
+		.help = "sequence number for message",
+		.next = NEXT(NEXT_ENTRY(ITEM_L2TPV2_MSG_CTRL_NS,
+					ITEM_L2TPV2_COMMON, ITEM_NEXT),
+			     NEXT_ENTRY(COMMON_UNSIGNED),
+			     item_param),
+		.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2,
+					     hdr.type3.ns)),
+	},
+	[ITEM_L2TPV2_MSG_CTRL_NR] = {
+		.name = "nr",
+		.help = "sequence number for next receive message",
+		.next = NEXT(NEXT_ENTRY(ITEM_L2TPV2_MSG_CTRL_NS,
+					ITEM_L2TPV2_COMMON, ITEM_NEXT),
+			     NEXT_ENTRY(COMMON_UNSIGNED),
+			     item_param),
+		.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2,
+					     hdr.type3.nr)),
+	},
+	[ITEM_PPP] = {
+		.name = "ppp",
+		.help = "match PPP header",
+		.priv = PRIV_ITEM(PPP, sizeof(struct rte_flow_item_ppp)),
+		.next = NEXT(item_ppp),
+		.call = parse_vc,
+	},
+	[ITEM_PPP_ADDR] = {
+		.name = "addr",
+		.help = "PPP address",
+		.next = NEXT(item_ppp, NEXT_ENTRY(COMMON_UNSIGNED),
+			     item_param),
+		.args = ARGS(ARGS_ENTRY(struct rte_flow_item_ppp, hdr.addr)),
+	},
+	[ITEM_PPP_CTRL] = {
+		.name = "ctrl",
+		.help = "PPP control",
+		.next = NEXT(item_ppp, NEXT_ENTRY(COMMON_UNSIGNED),
+			     item_param),
+		.args = ARGS(ARGS_ENTRY(struct rte_flow_item_ppp, hdr.ctrl)),
+	},
+	[ITEM_PPP_PROTO_ID] = {
+		.name = "proto_id",
+		.help = "PPP protocol identifier",
+		.next = NEXT(item_ppp, NEXT_ENTRY(COMMON_UNSIGNED),
+			     item_param),
+		.args = ARGS(ARGS_ENTRY(struct rte_flow_item_ppp,
+					hdr.proto_id)),
+	},
 	/* Validate/create actions. */
 	[ACTIONS] = {
 		.name = "actions",
@@ -5676,6 +5870,57 @@ parse_vc_item_ecpri_type(struct context *ctx, const struct token *token,
 	return len;
 }
 
+/** Parse L2TPv2 common header type field. */
+static int
+parse_vc_item_l2tpv2_type(struct context *ctx, const struct token *token,
+			 const char *str, unsigned int len,
+			 void *buf, unsigned int size)
+{
+	struct rte_flow_item_l2tpv2 *l2tpv2;
+	struct rte_flow_item_l2tpv2 *l2tpv2_mask;
+	struct rte_flow_item *item;
+	uint32_t data_size;
+	uint8_t msg_type = 0;
+	struct buffer *out = buf;
+	const struct arg *arg;
+
+	(void)size;
+	/* Token name must match. */
+	if (parse_default(ctx, token, str, len, NULL, 0) < 0)
+		return -1;
+	switch (ctx->curr) {
+	case ITEM_L2TPV2_COMMON_TYPE_DATA_L:
+		msg_type |= 0x4000;
+		break;
+	case ITEM_L2TPV2_COMMON_TYPE_CTRL:
+		msg_type |= 0xC800;
+		break;
+	default:
+		return -1;
+	}
+	if (!ctx->object)
+		return len;
+	arg = pop_args(ctx);
+	if (!arg)
+		return -1;
+	l2tpv2 = (struct rte_flow_item_l2tpv2 *)out->args.vc.data;
+	l2tpv2->hdr.common.flags_version |= msg_type;
+	data_size = ctx->objdata / 3; /* spec, last, mask */
+	l2tpv2_mask = (struct rte_flow_item_l2tpv2 *)(out->args.vc.data +
+						    (data_size * 2));
+	l2tpv2_mask->hdr.common.flags_version = 0xFFFF;
+	if (arg->hton) {
+		l2tpv2->hdr.common.flags_version =
+			rte_cpu_to_be_16(l2tpv2->hdr.common.flags_version);
+		l2tpv2_mask->hdr.common.flags_version =
+		    rte_cpu_to_be_16(l2tpv2_mask->hdr.common.flags_version);
+	}
+	item = &out->args.vc.pattern[out->args.vc.pattern_n - 1];
+	item->spec = l2tpv2;
+	item->mask = l2tpv2_mask;
+	return len;
+}
+
 /** Parse meter color action type. */
 static int
 parse_vc_action_meter_color_type(struct context *ctx, const struct token *token,
@@ -8701,6 +8946,12 @@ flow_item_default_mask(const struct rte_flow_item *item)
 	case RTE_FLOW_ITEM_TYPE_REPRESENTED_PORT:
 		mask = &rte_flow_item_ethdev_mask;
 		break;
+	case RTE_FLOW_ITEM_TYPE_L2TPV2:
+		mask = &rte_flow_item_l2tpv2_mask;
+		break;
+	case RTE_FLOW_ITEM_TYPE_PPP:
+		mask = &rte_flow_item_ppp_mask;
+		break;
 	default:
 		break;
 	}
diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
index 6d127d9a7b..31d6e1b293 100644
--- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
+++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
@@ -3810,6 +3810,20 @@ This section lists supported pattern items and their attributes, if any.
 
   - ``ethdev_port_id {unsigned}``: ethdev port ID
 
+- ``l2tpv2``: match L2TPv2 header.
+
+  - ``length {unsigned}``: L2TPv2 option length.
+  - ``tunnel_id {unsigned}``: L2TPv2 tunnel identifier.
+  - ``session_id {unsigned}``: L2TPv2 session identifier.
+  - ``ns {unsigned}``: L2TPv2 option ns.
+  - ``nr {unsigned}``: L2TPv2 option nr.
+
+- ``ppp``: match PPP header.
+
+  - ``addr {unsigned}``: PPP address.
+  - ``ctrl {unsigned}``: PPP control.
+  - ``proto_id {unsigned}``: PPP protocol identifier.
+
 Actions list
 ^^^^^^^^^^^^
 
@@ -5036,6 +5050,20 @@ The meter policy action list: ``green -> green, yellow -> yellow, red -> red``.
    testpmd> create port meter 0 1 13 1 yes 0xffff 0 0
    testpmd> flow create 0 priority 0 ingress group 1 pattern eth / end actions meter mtr_id 1 / end
 
+Sample PPPoL2TPv2oUDP RSS rules
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+PPPoL2TPv2oUDP RSS rules can be created by the following commands::
+
+ testpmd> flow create 0 ingress pattern eth / ipv4 / udp / l2tpv2 / ppp / ipv4
+          / end actions rss types ipv4 end queues end / end
+ testpmd> flow create 0 ingress pattern eth / ipv4 / udp / l2tpv2 / ppp / ipv6
+          / udp / end actions rss types ipv6-udp end queues end / end
+ testpmd> flow create 0 ingress pattern eth / ipv6 / udp / l2tpv2 / ppp / ipv4
+          / tcp / end actions rss types ipv4-tcp end queues end / end
+ testpmd> flow create 0 ingress pattern eth / ipv6 / udp / l2tpv2 / ppp / ipv6
+          / end actions rss types ipv6 end queues end / end
+
 BPF Functions
 --------------
 
-- 
2.25.1


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

* Re: [dpdk-dev] [PATCH v9 1/3] ethdev: support L2TPv2 and PPP procotol
  2021-10-21 10:49                 ` [dpdk-dev] [PATCH v9 1/3] ethdev: support L2TPv2 and PPP procotol Jie Wang
@ 2021-10-21 12:16                   ` Ferruh Yigit
  0 siblings, 0 replies; 71+ messages in thread
From: Ferruh Yigit @ 2021-10-21 12:16 UTC (permalink / raw)
  To: Jie Wang, dev
  Cc: orika, thomas, andrew.rybchenko, xiaoyun.li, stevex.yang,
	jingjing.wu, beilei.xing, wenjun1.wu, qi.z.zhang

On 10/21/2021 11:49 AM, Jie Wang wrote:
> diff --git a/doc/api/doxy-api-index.md b/doc/api/doxy-api-index.md
> index 1992107a03..42db196afe 100644
> --- a/doc/api/doxy-api-index.md
> +++ b/doc/api/doxy-api-index.md
> @@ -121,6 +121,8 @@ The public API headers are grouped by topics:
>     [VXLAN]              (@ref rte_vxlan.h),
>     [Geneve]             (@ref rte_geneve.h),
>     [eCPRI]              (@ref rte_ecpri.h)
> +  [L2TPv2]             (@ref rte_l2tpv2.h)
> +  [PPP]                (@ref rte_ppp.h)

',' are missing at the end, I will add them while merging.

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

* Re: [dpdk-dev] [PATCH v9 0/3] support PPPoL2TPv2oUDP RSS Hash
  2021-10-21 10:49               ` [dpdk-dev] [PATCH v9 0/3] support PPPoL2TPv2oUDP RSS Hash Jie Wang
                                   ` (2 preceding siblings ...)
  2021-10-21 10:49                 ` [dpdk-dev] [PATCH v9 3/3] app/testpmd: support L2TPv2 and PPP protocol pattern Jie Wang
@ 2021-10-21 12:17                 ` Ferruh Yigit
  3 siblings, 0 replies; 71+ messages in thread
From: Ferruh Yigit @ 2021-10-21 12:17 UTC (permalink / raw)
  To: Jie Wang, dev
  Cc: orika, thomas, andrew.rybchenko, xiaoyun.li, stevex.yang,
	jingjing.wu, beilei.xing, wenjun1.wu, qi.z.zhang

On 10/21/2021 11:49 AM, Jie Wang wrote:
> Support IAVF PPPoL2TPv2oUDP RSS Hash. Required to distribute packets
> based on inner IP src+dest address and TCP/UDP src+dest port.
> 
> ---
> v9:
>   * update comments and commit log.
>   * remove unnecessary '__rte_packed'.
> v8:
>   * added '__rte_packed' in new protocol header.
>   * update the comment in new protocol header file.
> V7:
>   * update ini file.
>   * modify irregular spelling.
> v6:
>   * update release notes.
>   * update lib/net/meson.build.
>   * update testpmd_funcs.rst.
>   * update doxygen comments in header files.
>   * update doc/api/doxy-api-index.md.
> v5: update release notes.
> v4:
>   * update commit log.
>   * redefine PPP protocol header.
>   * delete l2tpv2_encap.
> v3:
>   * add testpmd match PPP and L2TPv2 protocol header fields value.
>   * add the code of l2tpv2_encap.
>   * update the title of ethdev patch and adjust the position of
>     the added code.
> v2:
>   * update the rte_flow.rst and release notes.
>   * update l2tpv2 header format.
> 
> Jie Wang (3):
>    ethdev: support L2TPv2 and PPP procotol
>    net/iavf: support PPPoL2TPv2oUDP RSS Hash
>    app/testpmd: support L2TPv2 and PPP protocol pattern
> 

For series,
Reviewed-by: Ferruh Yigit <ferruh.yigit@intel.com>

Series applied to dpdk-next-net/main, thanks.

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

* Re: [dpdk-dev] [PATCH v7 1/3] ethdev: support L2TPv2 and PPP procotol
  2021-10-21  8:41                 ` Wang, Jie1X
@ 2021-10-21 13:18                   ` Ori Kam
  0 siblings, 0 replies; 71+ messages in thread
From: Ori Kam @ 2021-10-21 13:18 UTC (permalink / raw)
  To: Wang, Jie1X, dev
  Cc: Yigit, Ferruh, NBU-Contact-Thomas Monjalon, andrew.rybchenko, Li,
	Xiaoyun, Yang,  SteveX, Wu, Jingjing, Xing, Beilei, Wu, Wenjun1,
	Zhang, Qi Z

Hi Jie

> -----Original Message-----
> From: dev <dev-bounces@dpdk.org> On Behalf Of Wang, Jie1X
> Sent: Thursday, October 21, 2021 11:41 AM
> Subject: Re: [dpdk-dev] [PATCH v7 1/3] ethdev: support L2TPv2 and PPP procotol
> 
> 
> 
> > -----Original Message-----
> > From: Ori Kam <orika@nvidia.com>
> > Sent: Thursday, October 21, 2021 3:50 PM
> > To: Wang, Jie1X <jie1x.wang@intel.com>; dev@dpdk.org
> > Cc: Yigit, Ferruh <ferruh.yigit@intel.com>; NBU-Contact-Thomas Monjalon
> > <thomas@monjalon.net>; andrew.rybchenko@oktetlabs.ru; Li, Xiaoyun
> > <xiaoyun.li@intel.com>; Yang, SteveX <stevex.yang@intel.com>; Wu, Jingjing
> > <jingjing.wu@intel.com>; Xing, Beilei <beilei.xing@intel.com>; Wu, Wenjun1
> > <wenjun1.wu@intel.com>; Zhang, Qi Z <qi.z.zhang@intel.com>
> > Subject: RE: [PATCH v7 1/3] ethdev: support L2TPv2 and PPP procotol
> >
> > Hi Jie,
> >
> > > -----Original Message-----
> > > From: Jie Wang <jie1x.wang@intel.com>
> > > Sent: Thursday, October 21, 2021 9:26 AM
> > > Subject: [PATCH v7 1/3] ethdev: support L2TPv2 and PPP procotol
> > >
> > > Added flow pattern items and header formats of L2TPv2 and PPP.
> > >
> > > Signed-off-by: Wenjun Wu <wenjun1.wu@intel.com>
> > > Signed-off-by: Jie Wang <jie1x.wang@intel.com>
> > > ---
> > >  doc/api/doxy-api-index.md              |   2 +
> > >  doc/guides/nics/features/default.ini   |   2 +
> > >  doc/guides/nics/features/iavf.ini      |   2 +
> > >  doc/guides/prog_guide/rte_flow.rst     |  25 +++
> > >  doc/guides/rel_notes/release_21_11.rst |   4 +
> > >  lib/ethdev/rte_flow.c                  |   2 +
> > >  lib/ethdev/rte_flow.h                  |  65 +++++++
> > >  lib/net/meson.build                    |   2 +
> > >  lib/net/rte_l2tpv2.h                   | 234 +++++++++++++++++++++++++
> > >  lib/net/rte_ppp.h                      |  34 ++++
> > >  10 files changed, 372 insertions(+)
> > >  create mode 100644 lib/net/rte_l2tpv2.h  create mode 100644
> > > lib/net/rte_ppp.h
> > >
> > > diff --git a/doc/api/doxy-api-index.md b/doc/api/doxy-api-index.md
> > > index 1992107a03..42db196afe 100644
> > > --- a/doc/api/doxy-api-index.md
> > > +++ b/doc/api/doxy-api-index.md
> > > @@ -121,6 +121,8 @@ The public API headers are grouped by topics:
> > >    [VXLAN]              (@ref rte_vxlan.h),
> > >    [Geneve]             (@ref rte_geneve.h),
> > >    [eCPRI]              (@ref rte_ecpri.h)
> > > +  [L2TPv2]             (@ref rte_l2tpv2.h)
> > > +  [PPP]                (@ref rte_ppp.h)
> > >
> > >  - **QoS**:
> > >    [metering]           (@ref rte_meter.h),
> > > diff --git a/doc/guides/nics/features/default.ini
> > > b/doc/guides/nics/features/default.ini
> > > index 09914b1ad3..8e6a28c419 100644
> > > --- a/doc/guides/nics/features/default.ini
> > > +++ b/doc/guides/nics/features/default.ini
> > > @@ -110,6 +110,7 @@ ipv4                 =
> > >  ipv6                 =
> > >  ipv6_ext             =
> > >  ipv6_frag_ext        =
> > > +l2tpv2               =
> > >  l2tpv3oip            =
> > >  mark                 =
> > >  meta                 =
> > > @@ -121,6 +122,7 @@ pfcp                 =
> > >  phy_port             =
> > >  port_id              =
> > >  port_representor     =
> > > +ppp                  =
> > >  pppoed               =
> > >  pppoes               =
> > >  pppoe_proto_id       =
> > > diff --git a/doc/guides/nics/features/iavf.ini
> > > b/doc/guides/nics/features/iavf.ini
> > > index d00ca934c3..a916275b88 100644
> > > --- a/doc/guides/nics/features/iavf.ini
> > > +++ b/doc/guides/nics/features/iavf.ini
> > > @@ -50,8 +50,10 @@ icmp6                = Y
> > >  ipv4                 = Y
> > >  ipv6                 = Y
> > >  ipv6_frag_ext        = Y
> > > +l2tpv2               = Y
> > >  l2tpv3oip            = Y
> > >  pfcp                 = Y
> > > +ppp                  = Y
> > >  sctp                 = Y
> > >  tcp                  = Y
> > >  udp                  = Y
> > > diff --git a/doc/guides/prog_guide/rte_flow.rst
> > > b/doc/guides/prog_guide/rte_flow.rst
> > > index aeba374182..a2169517c3 100644
> > > --- a/doc/guides/prog_guide/rte_flow.rst
> > > +++ b/doc/guides/prog_guide/rte_flow.rst
> > > @@ -1573,6 +1573,31 @@ rte_flow_flex_item_create() routine.
> > >    as padded with trailing zeroes up to full configured length, both for
> > >    value and mask.
> > >
> > > +Item: ``L2TPV2``
> > > +^^^^^^^^^^^^^^^^^^^
> > > +
> > > +Matches a L2TPv2 header.
> > > +
> > > +- ``flags_version``: flags(12b), version(4b).
> > > +- ``length``: total length of the message.
> > > +- ``tunnel_id``: identifier for the control connection.
> > > +- ``session_id``: identifier for a session within a tunnel.
> > > +- ``ns``: sequence number for this date or control message.
> > > +- ``nr``: sequence number expected in the next control message to be
> > received.
> > > +- ``offset_size``: offset of payload data.
> > > +- ``offset_padding``: offset padding, variable length.
> > > +- Default ``mask`` matches flags_version only.
> > > +
> > > +Item: ``PPP``
> > > +^^^^^^^^^^^^^^^^^^^
> > > +
> > > +Matches a PPP header.
> > > +
> > > +- ``addr``: PPP address.
> > > +- ``ctrl``: PPP control.
> > > +- ``proto_id``: PPP protocol identifier.
> > > +- Default ``mask`` matches addr, ctrl, proto_id.
> > > +
> > >  Actions
> > >  ~~~~~~~
> > >
> > > diff --git a/doc/guides/rel_notes/release_21_11.rst
> > > b/doc/guides/rel_notes/release_21_11.rst
> > > index 041383ee2a..283770131c 100644
> > > --- a/doc/guides/rel_notes/release_21_11.rst
> > > +++ b/doc/guides/rel_notes/release_21_11.rst
> > > @@ -105,6 +105,10 @@ New Features
> > >
> > >    Added an ethdev API which can help users get device configuration.
> > >
> > > +* **Added L2TPv2 and PPP protocol support in rte_flow.**
> > > +
> > > +  Added flow pattern items and header formats of L2TPv2 and PPP protocol.
> > > +
> > >  * **Updated AF_XDP PMD.**
> > >
> > >    * Disabled secondary process support.
> > > diff --git a/lib/ethdev/rte_flow.c b/lib/ethdev/rte_flow.c index
> > > bcf0513b3c..d268784532 100644
> > > --- a/lib/ethdev/rte_flow.c
> > > +++ b/lib/ethdev/rte_flow.c
> > > @@ -156,6 +156,8 @@ static const struct rte_flow_desc_data
> > rte_flow_desc_item[] = {
> > >  	MK_FLOW_ITEM(REPRESENTED_PORT, sizeof(struct
> > rte_flow_item_ethdev)),
> > >  	MK_FLOW_ITEM_FN(FLEX, sizeof(struct rte_flow_item_flex),
> > >  			rte_flow_item_flex_conv),
> > > +	MK_FLOW_ITEM(L2TPV2, sizeof(struct rte_flow_item_l2tpv2)),
> > > +	MK_FLOW_ITEM(PPP, sizeof(struct rte_flow_item_ppp)),
> > >  };
> > >
> > >  /** Generate flow_action[] entry. */
> > > diff --git a/lib/ethdev/rte_flow.h b/lib/ethdev/rte_flow.h index
> > > 64ed7f2618..300e99e16b 100644
> > > --- a/lib/ethdev/rte_flow.h
> > > +++ b/lib/ethdev/rte_flow.h
> > > @@ -35,6 +35,8 @@
> > >  #include <rte_mbuf_dyn.h>
> > >  #include <rte_meter.h>
> > >  #include <rte_gtp.h>
> > > +#include <rte_l2tpv2.h>
> > > +#include <rte_ppp.h>
> > >
> > >  #ifdef __cplusplus
> > >  extern "C" {
> > > @@ -644,6 +646,20 @@ enum rte_flow_item_type {
> > >  	 * @see struct rte_flow_item_flex.
> > >  	 */
> > >  	RTE_FLOW_ITEM_TYPE_FLEX,
> > > +
> > > +	/**
> > > +	 * Matches L2TPv2 Header.
> > > +	 *
> > > +	 * See struct rte_flow_item_l2tpv2.
> > > +	 */
> > > +	RTE_FLOW_ITEM_TYPE_L2TPV2,
> > > +
> > > +	/**
> > > +	 * Matches PPP Header.
> > > +	 *
> > > +	 * See struct rte_flow_item_ppp.
> > > +	 */
> > > +	RTE_FLOW_ITEM_TYPE_PPP,
> > >  };
> > >
> > >  /**
> > > @@ -1900,6 +1916,55 @@ static const struct rte_flow_item_ethdev
> > > rte_flow_item_ethdev_mask = {  };  #endif
> > >
> > > +/**
> > > + * @warning
> > > + * @b EXPERIMENTAL: this structure may change without prior notice
> > > + * RTE_FLOW_ITEM_TYPE_L2TPV2
> > > + *
> > > + * Matches L2TPv2 Header
> > > + */
> > > +struct rte_flow_item_l2tpv2 {
> > > +	struct rte_l2tpv2_combined_msg_hdr hdr; };
> > > +
> > > +/** Default mask for RTE_FLOW_ITEM_TYPE_L2TPV2. */ #ifndef
> > > +__cplusplus static const struct rte_flow_item_l2tpv2
> > > +rte_flow_item_l2tpv2_mask = {
> > > +	/*
> > > +	 * flags and version bit mask
> > > +	 * 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0
> > > +	 * T L x x S x O P x x x x V V V V
> > > +	 */
> > > +	.hdr = {
> > > +		.common = {
> > > +			.flags_version = RTE_BE16(0xcb0f),
> > > +		},
> > > +	},
> > > +};
> > > +#endif
> > > +
> > > +/**
> > > + * @warning
> > > + * @b EXPERIMENTAL: this structure may change without prior notice
> > > + * RTE_FLOW_ITEM_TYPE_PPP
> > > + *
> > > + * Matches PPP Header
> > > + */
> > > +struct rte_flow_item_ppp {
> > > +	struct rte_ppp_hdr hdr;
> > > +};
> > > +
> > > +/** Default mask for RTE_FLOW_ITEM_TYPE_PPP. */ #ifndef __cplusplus
> > > +static const struct rte_flow_item_ppp rte_flow_item_ppp_mask = {
> > > +	.hdr = {
> > > +		.addr = 0xff,
> > > +		.ctrl = 0xff,
> > > +		.proto_id = RTE_BE16(0xffff),
> > > +	}
> > > +};
> > > +#endif
> > > +
> > >  /**
> > >   * Matching pattern item definition.
> > >   *
> > > diff --git a/lib/net/meson.build b/lib/net/meson.build index
> > > a4e395e9c5..e899846578 100644
> > > --- a/lib/net/meson.build
> > > +++ b/lib/net/meson.build
> > > @@ -19,6 +19,8 @@ headers = files(
> > >          'rte_higig.h',
> > >          'rte_ecpri.h',
> > >          'rte_geneve.h',
> > > +        'rte_l2tpv2.h',
> > > +        'rte_ppp.h',
> > >  )
> > >
> > >  sources = files(
> > > diff --git a/lib/net/rte_l2tpv2.h b/lib/net/rte_l2tpv2.h new file mode
> > > 100644 index 0000000000..18ea759ff4
> > > --- /dev/null
> > > +++ b/lib/net/rte_l2tpv2.h
> > > @@ -0,0 +1,234 @@
> > > +/* SPDX-License-Identifier: BSD-3-Clause
> > > + * Copyright 2021 Mellanox Technologies, Ltd  */
> > > +
> > > +#ifndef _RTE_L2TPV2_H_
> > > +#define _RTE_L2TPV2_H_
> > > +
> > > +/**
> > > + * @file
> > > + *
> > > + * L2TP header:
> > > + *
> > > + * `-0--------------------1----------------2-------------------3`
> > > + *
> > > + * `-0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1`
> > > + *
> > > + *
> > > +`+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+`
> > > + *
> > > + * `|T|L|x|x|S|x|O|P|x|x|x|x|--Ver--|-----------Length
> > > +(opt)--------|`
> > > + *
> > > + *
> > > +`+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+`
> > > + *
> > > + * `|-----------Tunnel ID-----------|-----------Session
> > > +ID----------|`
> > > + *
> > > + *
> > > +`+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+`
> > > + *
> > > + * `|-----------Ns (opt)------------|-----------Nr
> > > +(opt)------------|`
> > > + *
> > > + *
> > > +`+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+`
> > > + *
> > > + * `|---------Offset Size (opt)-----|---------Offset pad... (opt)`
> > > + *
> > > + *
> > > +`+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+`
> > > + *
> > > + * The Type (T) bit indicates the type of message. It is set to 0 for
> > > +a data
> > > + * message and 1 for a control message.
> > > + *
> > > + * If the Length (L) bit is 1, the Length field is present. This bit
> > > +MUST be
> > > + * set to 1 for control messages.
> > > + *
> > > + * The x bits are reserved for future extensions. All reserved bits
> > > +MUST
> > > + * be set to 0 on outgoing messages and ignored on incoming messages.
> > > + *
> > > + * If the Sequence (S) bit is set to 1 the Ns and Nr fields are present.
> > > + * The S bit MUST be set to 1 for control messages.
> > > + *
> > > + * If the Offset (O) bit is 1, the Offset Size field is present. The
> > > +O
> > > + * bit MUST be set to 0 for control messages.
> > > + *
> > > + * If the Priority (P) bit is 1, this data message should receive
> > > + * preferential treatment in its local queuing and transmission.
> > > + * The P bit MUST be set to 0 for control messages.
> > > + *
> > > + * Ver MUST be 2, indicating the version of the L2TP data message header.
> > > + *
> > > + * The Length field indicates the total length of the message in octets.
> > > + *
> > > + * Tunnel ID indicates the identifier for the control connection.
> > > + *
> > > + * Session ID indicates the identifier for a session within a tunnel.
> > > + *
> > > + * Ns indicates the sequence number for this data or control message.
> > > + *
> > > + * Nr indicates the sequence number expected in the next control
> > > +message
> > > + * to be received.
> > > + *
> > > + * The Offset Size field, if present, specifies the number of octets
> > > + * past the L2TP header at which the payload data is expected to start.
> > > + * Actual data within the offset padding is undefined. If the offset
> > > + * field is present, the L2TP header ends after the last octet of the
> > > + * offset padding.
> > > + */
> > > +
> > > +#include <stdint.h>
> > > +#include <rte_byteorder.h>
> > > +
> > > +#ifdef __cplusplus
> > > +extern "C" {
> > > +#endif
> > > +
> > > +/**
> > > + * L2TPv2 Common Header
> > > + */
> > > +RTE_STD_C11
> > > +struct rte_l2tpv2_common_hdr {
> > > +	union {
> > > +		/** header flags and protocol version */
> > > +		rte_be16_t flags_version;
> > > +		struct {
> > > +#if RTE_BYTE_ORDER == RTE_LITTLE_ENDIAN
> > > +			rte_be16_t t:1;		/**< message Type */
> > > +			rte_be16_t l:1;		/**< length option bit */
> > > +			rte_be16_t res1:2;	/**< reserved */
> > > +			rte_be16_t s:1;		/**< ns/nr option bit */
> > > +			rte_be16_t res2:1;	/**< reserved */
> > > +			rte_be16_t o:1;		/**< offset option bit */
> > > +			rte_be16_t p:1;		/**< priority option bit */
> > > +			rte_be16_t res3:4;	/**< reserved */
> > > +			rte_be16_t ver:4;	/**< protocol version */
> > > +#elif RTE_BYTE_ORDER == RTE_BIG_ENDIAN
> > > +			rte_be16_t ver:4;	/**< protocol version */
> > > +			rte_be16_t res3:4;	/**< reserved */
> > > +			rte_be16_t p:1;		/**< priority option bit */
> > > +			rte_be16_t o:1;		/**< offset option bit */
> > > +			rte_be16_t res2:1;	/**< reserved */
> > > +			rte_be16_t s:1;		/**< ns/nr option bit */
> > > +			rte_be16_t res1:2;	/**< reserved */
> > > +			rte_be16_t l:1;		/**< length option bit */
> > > +			rte_be16_t t:1;		/**< message Type */
> > > +#endif
> > > +		};
> > > +	};
> > > +};
> > > +
> > > +/**
> > > + * L2TPv2 message Header contains all options(length, ns, nr,
> > > + * offset size, offset padding).
> > > + */
> > > +struct rte_l2tpv2_msg_with_all_options {
> > > +	rte_be16_t length;		/**< length(16) */
> > > +	rte_be16_t tunnel_id;		/**< tunnel ID(16) */
> > > +	rte_be16_t session_id;		/**< session ID(16) */
> > > +	rte_be16_t ns;			/**< Ns(16) */
> > > +	rte_be16_t nr;			/**< Nr(16) */
> > > +	rte_be16_t offset_size;		/**< offset size(16) */
> > > +	uint8_t   *offset_padding;	/**< offset padding(variable length) */
> > > +};
> > > +
> > > +/**
> > > + * L2TPv2 message Header contains all options except length(ns, nr,
> > > + * offset size, offset padding).
> > > + */
> > > +struct rte_l2tpv2_msg_without_length {
> > > +	rte_be16_t tunnel_id;		/**< tunnel ID(16) */
> > > +	rte_be16_t session_id;		/**< session ID(16) */
> > > +	rte_be16_t ns;			/**< Ns(16) */
> > > +	rte_be16_t nr;			/**< Nr(16) */
> > > +	rte_be16_t offset_size;		/**< offset size(16) */
> > > +	uint8_t   *offset_padding;	/**< offset padding(variable length) */
> > > +};
> > > +
> > > +/**
> > > + * L2TPv2 message Header contains all options except ns_nr(length,
> > > + * offset size, offset padding).
> > > + * Ns and Nr MUST be toghter.
> > > + */
> > > +struct rte_l2tpv2_msg_without_ns_nr {
> > > +	rte_be16_t length;		/**< length(16) */
> > > +	rte_be16_t tunnel_id;		/**< tunnel ID(16) */
> > > +	rte_be16_t session_id;		/**< session ID(16) */
> > > +	rte_be16_t offset_size;		/**< offset size(16) */
> > > +	uint8_t   *offset_padding;	/**< offset padding(variable length) */
> > > +};
> > > +
> > > +/**
> > > + * L2TPv2 message Header contains all options except ns_nr(length, ns, nr).
> > > + * offset size and offset padding MUST be toghter.
> > > + */
> > > +struct rte_l2tpv2_msg_without_offset {
> > > +	rte_be16_t length;		/**< length(16) */
> > > +	rte_be16_t tunnel_id;		/**< tunnel ID(16) */
> > > +	rte_be16_t session_id;		/**< session ID(16) */
> > > +	rte_be16_t ns;			/**< Ns(16) */
> > > +	rte_be16_t nr;			/**< Nr(16) */
> > > +};
> >
> > Why not packed?
> >
> > > +
> > > +/**
> > > + * L2TPv2 message Header contains options offset size and offset padding.
> > > + */
> > > +struct rte_l2tpv2_msg_with_offset {
> > > +	rte_be16_t tunnel_id;		/**< tunnel ID(16) */
> > > +	rte_be16_t session_id;		/**< session ID(16) */
> > > +	rte_be16_t offset_size;		/**< offset size(16) */
> > > +	uint8_t   *offset_padding;	/**< offset padding(variable length) */
> > > +};
> > > +
> > > +/**
> > > + * L2TPv2 message Header contains options ns and nr.
> > > + */
> > > +struct rte_l2tpv2_msg_with_ns_nr {
> > > +	rte_be16_t tunnel_id;		/**< tunnel ID(16) */
> > > +	rte_be16_t session_id;		/**< session ID(16) */
> > > +	rte_be16_t ns;			/**< Ns(16) */
> > > +	rte_be16_t nr;			/**< Nr(16) */
> > > +};
> >
> > Why not packed? Same for all structs.
> >
> >
> Hi Ori,
> 
> Do you mean I should pack Ns/Nr into a structure as a field? And pack offset size/offset padding into
> another structure?
> 

I mean all the structures are defining protocols so I think they should be in packet format,
just like most of other protocol and even the ppp protocol.

> > > +
> > > +/**
> > > + * L2TPv2 message Header contains option length.
> > > + */
> > > +struct rte_l2tpv2_msg_with_length {
> > > +	rte_be16_t length;		/**< length(16) */
> > > +	rte_be16_t tunnel_id;		/**< tunnel ID(16) */
> > > +	rte_be16_t session_id;		/**< session ID(16) */
> > > +};
> > > +
> > > +/**
> > > + * L2TPv2 message Header without all options.
> > > + */
> > > +struct rte_l2tpv2_msg_without_all_options {
> > > +	rte_be16_t tunnel_id;		/**< tunnel ID(16) */
> > > +	rte_be16_t session_id;		/**< session ID(16) */
> > > +};
> > > +
> > > +/**
> > > + * L2TPv2 Combined Message Header Format: Common Header + Options  */
> > > +RTE_STD_C11
> > > +struct rte_l2tpv2_combined_msg_hdr {
> > > +	struct rte_l2tpv2_common_hdr common; /**< common header */
> > > +	union {
> > > +		/** header with all options */
> > > +		struct rte_l2tpv2_msg_with_all_options type0;
> > > +		/** header with all options except length */
> > > +		struct rte_l2tpv2_msg_without_length type1;
> > > +		/** header with all options except ns/nr */
> > > +		struct rte_l2tpv2_msg_without_ns_nr type2;
> > > +		/** header with all options except offset */
> > > +		struct rte_l2tpv2_msg_without_offset type3;
> > > +		/** header with offset options */
> > > +		struct rte_l2tpv2_msg_with_offset type4;
> > > +		/** header with ns/nr options */
> > > +		struct rte_l2tpv2_msg_with_ns_nr type5;
> > > +		/** header with length option */
> > > +		struct rte_l2tpv2_msg_with_length type6;
> > > +		/** header without all options */
> > > +		struct rte_l2tpv2_msg_without_all_options type7;
> > > +	};
> > > +};
> > > +
> > > +#ifdef __cplusplus
> > > +}
> > > +#endif
> > > +
> > > +#endif /* _RTE_L2TPV2_H_ */
> > > diff --git a/lib/net/rte_ppp.h b/lib/net/rte_ppp.h new file mode
> > > 100644 index 0000000000..2a53cd969f
> > > --- /dev/null
> > > +++ b/lib/net/rte_ppp.h
> > > @@ -0,0 +1,34 @@
> > > +/* SPDX-License-Identifier: BSD-3-Clause
> > > + * Copyright 2021 Mellanox Technologies, Ltd  */
> > > +
> > > +#ifndef _RTE_PPP_H_
> > > +#define _RTE_PPP_H_
> > > +
> > > +/**
> > > + * @file
> > > + *
> > > + * PPP headers definition.
> > > + */
> > > +
> > > +#include <stdint.h>
> > > +#include <rte_byteorder.h>
> > > +
> > > +#ifdef __cplusplus
> > > +extern "C" {
> > > +#endif
> > > +
> > > +/**
> > > + * PPP Header
> > > + */
> > > +struct rte_ppp_hdr {
> > > +	uint8_t addr; /**< PPP address(8) */
> > > +	uint8_t ctrl; /**< PPP control(8) */
> > > +	rte_be16_t proto_id; /**< PPP protocol identifier(16) */ }
> > > +__rte_packed;
> > > +
> > > +#ifdef __cplusplus
> > > +}
> > > +#endif
> > > +
> > > +#endif /* _RTE_PPP_H_ */
> > > --
> > > 2.25.1
> >
> > Best,
> > Ori

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

end of thread, other threads:[~2021-10-21 13:18 UTC | newest]

Thread overview: 71+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-09-24 15:17 [dpdk-dev] [PATCH 0/4] support PPPoL2TPv2oUDP RSS Hash Jie Wang
2021-09-24 15:17 ` [dpdk-dev] [PATCH 1/4] net/iavf: support PPPoL2TPv2oUDP over IPv4 " Jie Wang
2021-09-24 15:17 ` [dpdk-dev] [PATCH 2/4] app/testpmd: support PPPoL2TPv2oUDP " Jie Wang
2021-09-24 15:17 ` [dpdk-dev] [PATCH 3/4] ethdev: " Jie Wang
2021-09-30 14:38   ` Ori Kam
2021-10-05 14:42     ` Ferruh Yigit
2021-10-05 15:06       ` Ori Kam
2021-09-24 15:17 ` [dpdk-dev] [PATCH 4/4] net/iavf: support PPPoL2TPv2oUDP over IPv6 " Jie Wang
2021-10-12 10:25 ` [dpdk-dev] [PATCH v2 0/3] support PPPoL2TPv2oUDP " Jie Wang
2021-10-12 10:25   ` [dpdk-dev] [PATCH v2 1/3] net/iavf: " Jie Wang
2021-10-12 10:25   ` [dpdk-dev] [PATCH v2 2/3] app/testpmd: " Jie Wang
2021-10-12 15:31     ` Ori Kam
2021-10-13  8:15       ` Wang, Jie1X
2021-10-13  9:15         ` Ori Kam
2021-10-13  9:54           ` Wang, Jie1X
2021-10-13 10:19             ` Ori Kam
2021-10-12 10:25   ` [dpdk-dev] [PATCH v2 3/3] ethdev: " Jie Wang
2021-10-12 15:28     ` Ori Kam
2021-10-15  9:58   ` [dpdk-dev] [PATCH v3 0/3] " Jie Wang
2021-10-15  9:58     ` [dpdk-dev] [PATCH v3 1/3] ethdev: support PPP and L2TPV2 procotol Jie Wang
2021-10-15 11:10       ` Ferruh Yigit
2021-10-17  8:12         ` Ori Kam
2021-10-17  8:19       ` Ori Kam
2021-10-15  9:58     ` [dpdk-dev] [PATCH v3 2/3] net/iavf: support PPPoL2TPv2oUDP RSS Hash Jie Wang
2021-10-15  9:58     ` [dpdk-dev] [PATCH v3 3/3] app/testpmd: support L2TPV2 and PPP protocol pattern Jie Wang
2021-10-17  8:51       ` Ori Kam
2021-10-18  9:33     ` [dpdk-dev] [PATCH v4 0/3] support PPPoL2TPv2oUDP RSS Hash Jie Wang
2021-10-18  9:33       ` [dpdk-dev] [PATCH v4 1/3] ethdev: support PPP and L2TPV2 procotol Jie Wang
2021-10-18 10:56         ` Ori Kam
2021-10-18 12:39           ` Zhang, Qi Z
2021-10-18  9:33       ` [dpdk-dev] [PATCH v4 2/3] net/iavf: support PPPoL2TPv2oUDP RSS Hash Jie Wang
2021-10-18  9:33       ` [dpdk-dev] [PATCH v4 3/3] app/testpmd: support L2TPV2 and PPP protocol pattern Jie Wang
2021-10-18 11:03         ` Ori Kam
2021-10-18 12:41           ` Zhang, Qi Z
2021-10-19  3:08       ` [dpdk-dev] [PATCH v5 0/3] support PPPoL2TPv2oUDP RSS Hash Jie Wang
2021-10-19  3:08         ` [dpdk-dev] [PATCH v5 1/3] ethdev: support PPP and L2TPV2 procotol Jie Wang
2021-10-19  6:17           ` Ori Kam
2021-10-19 10:30           ` Ferruh Yigit
2021-10-19  3:08         ` [dpdk-dev] [PATCH v5 2/3] net/iavf: support PPPoL2TPv2oUDP RSS Hash Jie Wang
2021-10-20  1:57           ` Xing, Beilei
2021-10-19  3:08         ` [dpdk-dev] [PATCH v5 3/3] app/testpmd: support L2TPV2 and PPP protocol pattern Jie Wang
2021-10-19  9:41           ` Ferruh Yigit
2021-10-20  9:32         ` [dpdk-dev] [PATCH v6 0/3] support PPPoL2TPv2oUDP RSS Hash Jie Wang
2021-10-20  9:32           ` [dpdk-dev] [PATCH v6 1/3] ethdev: support PPP and L2TPV2 procotol Jie Wang
2021-10-20  9:53             ` Andrew Rybchenko
2021-10-20  9:32           ` [dpdk-dev] [PATCH v6 2/3] net/iavf: support PPPoL2TPv2oUDP RSS Hash Jie Wang
2021-10-21  2:07             ` Xing, Beilei
2021-10-20  9:32           ` [dpdk-dev] [PATCH v6 3/3] app/testpmd: support L2TPV2 and PPP protocol pattern Jie Wang
2021-10-21  6:26           ` [dpdk-dev] [PATCH v7 0/3] support PPPoL2TPv2oUDP RSS Hash Jie Wang
2021-10-21  6:26             ` [dpdk-dev] [PATCH v7 1/3] ethdev: support L2TPv2 and PPP procotol Jie Wang
2021-10-21  7:50               ` Ori Kam
2021-10-21  7:52                 ` Andrew Rybchenko
2021-10-21  8:28                   ` Wang, Jie1X
2021-10-21  8:30                     ` Andrew Rybchenko
2021-10-21  8:41                 ` Wang, Jie1X
2021-10-21 13:18                   ` Ori Kam
2021-10-21  9:26                 ` Ferruh Yigit
2021-10-21  9:29               ` Ferruh Yigit
2021-10-21  6:26             ` [dpdk-dev] [PATCH v7 2/3] net/iavf: support PPPoL2TPv2oUDP RSS Hash Jie Wang
2021-10-21  6:26             ` [dpdk-dev] [PATCH v7 3/3] app/testpmd: support L2TPv2 and PPP protocol pattern Jie Wang
2021-10-21 10:05             ` [dpdk-dev] [PATCH v8 0/3] support PPPoL2TPv2oUDP RSS Hash Jie Wang
2021-10-21 10:05               ` [dpdk-dev] [PATCH v8 1/3] ethdev: support L2TPv2 and PPP procotol Jie Wang
2021-10-21 10:13                 ` Andrew Rybchenko
2021-10-21 10:05               ` [dpdk-dev] [PATCH v8 2/3] net/iavf: support PPPoL2TPv2oUDP RSS Hash Jie Wang
2021-10-21 10:05               ` [dpdk-dev] [PATCH v8 3/3] app/testpmd: support L2TPv2 and PPP protocol pattern Jie Wang
2021-10-21 10:49               ` [dpdk-dev] [PATCH v9 0/3] support PPPoL2TPv2oUDP RSS Hash Jie Wang
2021-10-21 10:49                 ` [dpdk-dev] [PATCH v9 1/3] ethdev: support L2TPv2 and PPP procotol Jie Wang
2021-10-21 12:16                   ` Ferruh Yigit
2021-10-21 10:49                 ` [dpdk-dev] [PATCH v9 2/3] net/iavf: support PPPoL2TPv2oUDP RSS Hash Jie Wang
2021-10-21 10:49                 ` [dpdk-dev] [PATCH v9 3/3] app/testpmd: support L2TPv2 and PPP protocol pattern Jie Wang
2021-10-21 12:17                 ` [dpdk-dev] [PATCH v9 0/3] support PPPoL2TPv2oUDP RSS Hash Ferruh Yigit

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).