DPDK patches and discussions
 help / color / mirror / Atom feed
* [dpdk-dev] [PATCH v1] app/testpmd: enable GTP header parse and Tx checksum offload
@ 2019-10-17 15:26 Ting Xu
  2019-10-17 16:15 ` [dpdk-dev] [PATCH v2] " Ting Xu
  0 siblings, 1 reply; 20+ messages in thread
From: Ting Xu @ 2019-10-17 15:26 UTC (permalink / raw)
  To: dev; +Cc: wenzhuo.lu, jingjing.wu, bernard.iremonger, qi.z.zhang

This patch enables testpmd to forward GTP packet in csum fwd mode.
GTP header structure (without optional fields and extension header)
and parser function are added.  GTPU and GTPC packets are both
supported, with respective UDP destination port and GTP message
type. Currently, packet with outer IPv6 is not available.

Signed-off-by: Ting Xu <ting.xu@intel.com>
---
 app/test-pmd/csumonly.c | 109 ++++++++++++++++++++++++++++++++++++----
 1 file changed, 100 insertions(+), 9 deletions(-)

diff --git a/app/test-pmd/csumonly.c b/app/test-pmd/csumonly.c
index e1cb7fb70..00f099482 100644
--- a/app/test-pmd/csumonly.c
+++ b/app/test-pmd/csumonly.c
@@ -179,6 +179,84 @@ parse_ethernet(struct rte_ether_hdr *eth_hdr, struct testpmd_offload_info *info)
 	}
 }
 
+/*
+ * Parse a GTP protocol header.
+ * No optional fields and next extension header type.
+ */
+struct rte_gtp_hdr {
+	uint8_t gtp_hdr_info;
+	uint8_t msg_type;
+	uint16_t msg_len;
+	uint32_t teid;
+} __attribute__((__packed__));
+
+/* GTP header length */
+#define RTE_ETHER_GTP_HLEN \
+	(sizeof(struct rte_udp_hdr) + sizeof(struct rte_gtp_hdr))
+/* GTP next protocal type */
+#define RTE_GTP_TYPE_IPV4 0x40
+#define RTE_GTP_TYPE_IPV6 0x60
+
+static void
+parse_gtp(struct rte_udp_hdr *udp_hdr,
+	  struct testpmd_offload_info *info)
+{
+	struct rte_ipv4_hdr *ipv4_hdr;
+	struct rte_ipv6_hdr *ipv6_hdr;
+	struct rte_gtp_hdr *gtp_hdr;
+	uint8_t gtp_len = sizeof(*gtp_hdr);
+	uint8_t ip_ver;
+	/* GTP destination port number */
+	uint16_t gtp_udpc_port = 2123;
+	uint16_t gtp_udpu_port = 2152;
+
+	/* Check udp destination port. */
+	if (udp_hdr->dst_port != _htons(gtp_udpc_port) &&
+	    udp_hdr->src_port != _htons(gtp_udpc_port) &&
+	    udp_hdr->dst_port != _htons(gtp_udpu_port))
+		return;
+
+	info->is_tunnel = 1;
+	info->outer_ethertype = info->ethertype;
+	info->outer_l2_len = info->l2_len;
+	info->outer_l3_len = info->l3_len;
+	info->outer_l4_proto = info->l4_proto;
+	info->l2_len = 0;
+
+	gtp_hdr = (struct rte_gtp_hdr *)((char *)udp_hdr +
+		  sizeof(struct rte_udp_hdr));
+
+	/*
+	 * Check message type. If message type is 0xff, it is
+	 * a GTP data packet. If not, it is a GTP control packet
+	 */
+	if (gtp_hdr->msg_type == 0xff) {
+		ip_ver = *(uint8_t *)((char *)udp_hdr +
+			 sizeof(struct rte_udp_hdr) +
+			 sizeof(struct rte_gtp_hdr));
+		ip_ver = (ip_ver) & 0xf0;
+
+		if (ip_ver == RTE_GTP_TYPE_IPV4) {
+			ipv4_hdr = (struct rte_ipv4_hdr *)((char *)gtp_hdr +
+				   gtp_len);
+			info->ethertype = _htons(RTE_ETHER_TYPE_IPV4);
+			parse_ipv4(ipv4_hdr, info);
+		} else if (ip_ver == RTE_GTP_TYPE_IPV6) {
+			ipv6_hdr = (struct rte_ipv6_hdr *)((char *)gtp_hdr +
+				   gtp_len);
+			info->ethertype = _htons(RTE_ETHER_TYPE_IPV6);
+			parse_ipv6(ipv6_hdr, info);
+		}
+	} else {
+		info->ethertype = 0;
+		info->l4_len = 0;
+		info->l3_len = 0;
+		info->l4_proto = 0;
+	}
+
+	info->l2_len += RTE_ETHER_GTP_HLEN;
+}
+
 /* Parse a vxlan header */
 static void
 parse_vxlan(struct rte_udp_hdr *udp_hdr,
@@ -478,15 +556,22 @@ process_outer_cksums(void *outer_l3_hdr, struct testpmd_offload_info *info,
 	if (info->outer_l4_proto != IPPROTO_UDP)
 		return ol_flags;
 
+	udp_hdr = (struct rte_udp_hdr *)
+		((char *)outer_l3_hdr + info->outer_l3_len);
+
 	/* Skip SW outer UDP checksum generation if HW supports it */
 	if (tx_offloads & DEV_TX_OFFLOAD_OUTER_UDP_CKSUM) {
+		if (info->outer_ethertype == _htons(RTE_ETHER_TYPE_IPV4))
+			udp_hdr->dgram_cksum
+				= rte_ipv4_phdr_cksum(ipv4_hdr, ol_flags);
+		else
+			udp_hdr->dgram_cksum
+				= rte_ipv6_phdr_cksum(ipv6_hdr, ol_flags);
+
 		ol_flags |= PKT_TX_OUTER_UDP_CKSUM;
 		return ol_flags;
 	}
 
-	udp_hdr = (struct rte_udp_hdr *)
-		((char *)outer_l3_hdr + info->outer_l3_len);
-
 	/* outer UDP checksum is done in software. In the other side, for
 	 * UDP tunneling, like VXLAN or Geneve, outer UDP checksum can be
 	 * set to zero.
@@ -679,6 +764,7 @@ pkt_copy_split(const struct rte_mbuf *pkt)
  *           UDP|TCP|SCTP
  *   Ether / (vlan) / outer IP|IP6 / outer UDP / VXLAN-GPE / IP|IP6 /
  *           UDP|TCP|SCTP
+ *   Ether / (vlan) / outer IP / outer UDP / GTP / IP|IP6 / UDP|TCP|SCTP
  *   Ether / (vlan) / outer IP|IP6 / GRE / Ether / IP|IP6 / UDP|TCP|SCTP
  *   Ether / (vlan) / outer IP|IP6 / GRE / IP|IP6 / UDP|TCP|SCTP
  *   Ether / (vlan) / outer IP|IP6 / IP|IP6 / UDP|TCP|SCTP
@@ -784,18 +870,23 @@ pkt_burst_checksum_forward(struct fwd_stream *fs)
 		if (txp->parse_tunnel) {
 			if (info.l4_proto == IPPROTO_UDP) {
 				struct rte_udp_hdr *udp_hdr;
-
 				udp_hdr = (struct rte_udp_hdr *)
 					((char *)l3_hdr + info.l3_len);
-				parse_vxlan_gpe(udp_hdr, &info);
+				parse_gtp(udp_hdr, &info);
 				if (info.is_tunnel) {
-					tx_ol_flags |= PKT_TX_TUNNEL_VXLAN_GPE;
+					tx_ol_flags |= PKT_TX_TUNNEL_GTP;
 				} else {
-					parse_vxlan(udp_hdr, &info,
-						    m->packet_type);
-					if (info.is_tunnel)
+					parse_vxlan_gpe(udp_hdr, &info);
+					if (info.is_tunnel) {
 						tx_ol_flags |=
+							PKT_TX_TUNNEL_VXLAN_GPE;
+					} else {
+						parse_vxlan(udp_hdr, &info,
+							    m->packet_type);
+						if (info.is_tunnel)
+							tx_ol_flags |=
 							PKT_TX_TUNNEL_VXLAN;
+					}
 				}
 			} else if (info.l4_proto == IPPROTO_GRE) {
 				struct simple_gre_hdr *gre_hdr;
-- 
2.17.1


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

* [dpdk-dev] [PATCH v2] app/testpmd: enable GTP header parse and Tx checksum offload
  2019-10-17 15:26 [dpdk-dev] [PATCH v1] app/testpmd: enable GTP header parse and Tx checksum offload Ting Xu
@ 2019-10-17 16:15 ` Ting Xu
  2019-10-18 16:08   ` [dpdk-dev] [PATCH v3] " Ting Xu
  0 siblings, 1 reply; 20+ messages in thread
From: Ting Xu @ 2019-10-17 16:15 UTC (permalink / raw)
  To: dev; +Cc: wenzhuo.lu, jingjing.wu, bernard.iremonger, qi.z.zhang

This patch enables testpmd to forward GTP packet in csum fwd mode.
GTP header structure (without optional fields and extension header)
and parser function are added. GTPU and GTPC packets are both
supported, with respective UDP destination port and GTP message
type.

Signed-off-by: Ting Xu <ting.xu@intel.com>
---
 app/test-pmd/csumonly.c | 109 ++++++++++++++++++++++++++++++++++++----
 1 file changed, 100 insertions(+), 9 deletions(-)

diff --git a/app/test-pmd/csumonly.c b/app/test-pmd/csumonly.c
index e1cb7fb70..d34116f0b 100644
--- a/app/test-pmd/csumonly.c
+++ b/app/test-pmd/csumonly.c
@@ -179,6 +179,84 @@ parse_ethernet(struct rte_ether_hdr *eth_hdr, struct testpmd_offload_info *info)
 	}
 }
 
+/*
+ * Parse a GTP protocol header.
+ * No optional fields and next extension header type.
+ */
+struct rte_gtp_hdr {
+	uint8_t gtp_hdr_info;
+	uint8_t msg_type;
+	uint16_t msg_len;
+	uint32_t teid;
+} __attribute__((__packed__));
+
+/* GTP header length */
+#define RTE_ETHER_GTP_HLEN \
+	(sizeof(struct rte_udp_hdr) + sizeof(struct rte_gtp_hdr))
+/* GTP next protocal type */
+#define RTE_GTP_TYPE_IPV4 0x40
+#define RTE_GTP_TYPE_IPV6 0x60
+
+static void
+parse_gtp(struct rte_udp_hdr *udp_hdr,
+	  struct testpmd_offload_info *info)
+{
+	struct rte_ipv4_hdr *ipv4_hdr;
+	struct rte_ipv6_hdr *ipv6_hdr;
+	struct rte_gtp_hdr *gtp_hdr;
+	uint8_t gtp_len = sizeof(*gtp_hdr);
+	uint8_t ip_ver;
+	/* GTP destination port number */
+	uint16_t gtpc_udp_port = 2123;
+	uint16_t gtpu_udp_port = 2152;
+
+	/* Check udp destination port. */
+	if (udp_hdr->dst_port != _htons(gtpc_udp_port) &&
+	    udp_hdr->src_port != _htons(gtpc_udp_port) &&
+	    udp_hdr->dst_port != _htons(gtpu_udp_port))
+		return;
+
+	info->is_tunnel = 1;
+	info->outer_ethertype = info->ethertype;
+	info->outer_l2_len = info->l2_len;
+	info->outer_l3_len = info->l3_len;
+	info->outer_l4_proto = info->l4_proto;
+	info->l2_len = 0;
+
+	gtp_hdr = (struct rte_gtp_hdr *)((char *)udp_hdr +
+		  sizeof(struct rte_udp_hdr));
+
+	/*
+	 * Check message type. If message type is 0xff, it is
+	 * a GTP data packet. If not, it is a GTP control packet
+	 */
+	if (gtp_hdr->msg_type == 0xff) {
+		ip_ver = *(uint8_t *)((char *)udp_hdr +
+			 sizeof(struct rte_udp_hdr) +
+			 sizeof(struct rte_gtp_hdr));
+		ip_ver = (ip_ver) & 0xf0;
+
+		if (ip_ver == RTE_GTP_TYPE_IPV4) {
+			ipv4_hdr = (struct rte_ipv4_hdr *)((char *)gtp_hdr +
+				   gtp_len);
+			info->ethertype = _htons(RTE_ETHER_TYPE_IPV4);
+			parse_ipv4(ipv4_hdr, info);
+		} else if (ip_ver == RTE_GTP_TYPE_IPV6) {
+			ipv6_hdr = (struct rte_ipv6_hdr *)((char *)gtp_hdr +
+				   gtp_len);
+			info->ethertype = _htons(RTE_ETHER_TYPE_IPV6);
+			parse_ipv6(ipv6_hdr, info);
+		}
+	} else {
+		info->ethertype = 0;
+		info->l4_len = 0;
+		info->l3_len = 0;
+		info->l4_proto = 0;
+	}
+
+	info->l2_len += RTE_ETHER_GTP_HLEN;
+}
+
 /* Parse a vxlan header */
 static void
 parse_vxlan(struct rte_udp_hdr *udp_hdr,
@@ -478,15 +556,22 @@ process_outer_cksums(void *outer_l3_hdr, struct testpmd_offload_info *info,
 	if (info->outer_l4_proto != IPPROTO_UDP)
 		return ol_flags;
 
+	udp_hdr = (struct rte_udp_hdr *)
+		((char *)outer_l3_hdr + info->outer_l3_len);
+
 	/* Skip SW outer UDP checksum generation if HW supports it */
 	if (tx_offloads & DEV_TX_OFFLOAD_OUTER_UDP_CKSUM) {
+		if (info->outer_ethertype == _htons(RTE_ETHER_TYPE_IPV4))
+			udp_hdr->dgram_cksum
+				= rte_ipv4_phdr_cksum(ipv4_hdr, ol_flags);
+		else
+			udp_hdr->dgram_cksum
+				= rte_ipv6_phdr_cksum(ipv6_hdr, ol_flags);
+
 		ol_flags |= PKT_TX_OUTER_UDP_CKSUM;
 		return ol_flags;
 	}
 
-	udp_hdr = (struct rte_udp_hdr *)
-		((char *)outer_l3_hdr + info->outer_l3_len);
-
 	/* outer UDP checksum is done in software. In the other side, for
 	 * UDP tunneling, like VXLAN or Geneve, outer UDP checksum can be
 	 * set to zero.
@@ -679,6 +764,7 @@ pkt_copy_split(const struct rte_mbuf *pkt)
  *           UDP|TCP|SCTP
  *   Ether / (vlan) / outer IP|IP6 / outer UDP / VXLAN-GPE / IP|IP6 /
  *           UDP|TCP|SCTP
+ *   Ether / (vlan) / outer IP / outer UDP / GTP / IP|IP6 / UDP|TCP|SCTP
  *   Ether / (vlan) / outer IP|IP6 / GRE / Ether / IP|IP6 / UDP|TCP|SCTP
  *   Ether / (vlan) / outer IP|IP6 / GRE / IP|IP6 / UDP|TCP|SCTP
  *   Ether / (vlan) / outer IP|IP6 / IP|IP6 / UDP|TCP|SCTP
@@ -784,18 +870,23 @@ pkt_burst_checksum_forward(struct fwd_stream *fs)
 		if (txp->parse_tunnel) {
 			if (info.l4_proto == IPPROTO_UDP) {
 				struct rte_udp_hdr *udp_hdr;
-
 				udp_hdr = (struct rte_udp_hdr *)
 					((char *)l3_hdr + info.l3_len);
-				parse_vxlan_gpe(udp_hdr, &info);
+				parse_gtp(udp_hdr, &info);
 				if (info.is_tunnel) {
-					tx_ol_flags |= PKT_TX_TUNNEL_VXLAN_GPE;
+					tx_ol_flags |= PKT_TX_TUNNEL_GTP;
 				} else {
-					parse_vxlan(udp_hdr, &info,
-						    m->packet_type);
-					if (info.is_tunnel)
+					parse_vxlan_gpe(udp_hdr, &info);
+					if (info.is_tunnel) {
 						tx_ol_flags |=
+							PKT_TX_TUNNEL_VXLAN_GPE;
+					} else {
+						parse_vxlan(udp_hdr, &info,
+							    m->packet_type);
+						if (info.is_tunnel)
+							tx_ol_flags |=
 							PKT_TX_TUNNEL_VXLAN;
+					}
 				}
 			} else if (info.l4_proto == IPPROTO_GRE) {
 				struct simple_gre_hdr *gre_hdr;
-- 
2.17.1


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

* [dpdk-dev] [PATCH v3] app/testpmd: enable GTP header parse and Tx checksum offload
  2019-10-17 16:15 ` [dpdk-dev] [PATCH v2] " Ting Xu
@ 2019-10-18 16:08   ` Ting Xu
  2019-10-18 18:49     ` Ferruh Yigit
  2019-10-21 12:29     ` [dpdk-dev] [PATCH v4] " Ting Xu
  0 siblings, 2 replies; 20+ messages in thread
From: Ting Xu @ 2019-10-18 16:08 UTC (permalink / raw)
  To: dev; +Cc: wenzhuo.lu, jingjing.wu, bernard.iremonger, qi.z.zhang

This patch enables testpmd to forward GTP packet in csum fwd mode.
GTP header structure (without optional fields and extension header)
and parser function are added. GTPU and GTPC packets are both
supported, with respective UDP destination port and GTP message
type.

Signed-off-by: Ting Xu <ting.xu@intel.com>

---
v3: correct coding style issue.
v2: modify commit log
depend on patch: lib/mbuf: add GTP tunnel type flag.
---
 app/test-pmd/csumonly.c | 115 ++++++++++++++++++++++++++++++++++++----
 1 file changed, 104 insertions(+), 11 deletions(-)

diff --git a/app/test-pmd/csumonly.c b/app/test-pmd/csumonly.c
index e1cb7fb70..b7ff7c742 100644
--- a/app/test-pmd/csumonly.c
+++ b/app/test-pmd/csumonly.c
@@ -179,6 +179,84 @@ parse_ethernet(struct rte_ether_hdr *eth_hdr, struct testpmd_offload_info *info)
 	}
 }
 
+/*
+ * Parse a GTP protocol header.
+ * No optional fields and next extension header type.
+ */
+struct rte_gtp_hdr {
+	uint8_t gtp_hdr_info;
+	uint8_t msg_type;
+	uint16_t msg_len;
+	uint32_t teid;
+} __attribute__((__packed__));
+
+/* GTP header length */
+#define RTE_ETHER_GTP_HLEN \
+	(sizeof(struct rte_udp_hdr) + sizeof(struct rte_gtp_hdr))
+/* GTP next protocal type */
+#define RTE_GTP_TYPE_IPV4 0x40
+#define RTE_GTP_TYPE_IPV6 0x60
+
+static void
+parse_gtp(struct rte_udp_hdr *udp_hdr,
+	  struct testpmd_offload_info *info)
+{
+	struct rte_ipv4_hdr *ipv4_hdr;
+	struct rte_ipv6_hdr *ipv6_hdr;
+	struct rte_gtp_hdr *gtp_hdr;
+	uint8_t gtp_len = sizeof(*gtp_hdr);
+	uint8_t ip_ver;
+	/* GTP destination port number */
+	uint16_t gtpc_udp_port = 2123;
+	uint16_t gtpu_udp_port = 2152;
+
+	/* Check udp destination port. */
+	if (udp_hdr->dst_port != _htons(gtpc_udp_port) &&
+	    udp_hdr->src_port != _htons(gtpc_udp_port) &&
+	    udp_hdr->dst_port != _htons(gtpu_udp_port))
+		return;
+
+	info->is_tunnel = 1;
+	info->outer_ethertype = info->ethertype;
+	info->outer_l2_len = info->l2_len;
+	info->outer_l3_len = info->l3_len;
+	info->outer_l4_proto = info->l4_proto;
+	info->l2_len = 0;
+
+	gtp_hdr = (struct rte_gtp_hdr *)((char *)udp_hdr +
+		  sizeof(struct rte_udp_hdr));
+
+	/*
+	 * Check message type. If message type is 0xff, it is
+	 * a GTP data packet. If not, it is a GTP control packet
+	 */
+	if (gtp_hdr->msg_type == 0xff) {
+		ip_ver = *(uint8_t *)((char *)udp_hdr +
+			 sizeof(struct rte_udp_hdr) +
+			 sizeof(struct rte_gtp_hdr));
+		ip_ver = (ip_ver) & 0xf0;
+
+		if (ip_ver == RTE_GTP_TYPE_IPV4) {
+			ipv4_hdr = (struct rte_ipv4_hdr *)((char *)gtp_hdr +
+				   gtp_len);
+			info->ethertype = _htons(RTE_ETHER_TYPE_IPV4);
+			parse_ipv4(ipv4_hdr, info);
+		} else if (ip_ver == RTE_GTP_TYPE_IPV6) {
+			ipv6_hdr = (struct rte_ipv6_hdr *)((char *)gtp_hdr +
+				   gtp_len);
+			info->ethertype = _htons(RTE_ETHER_TYPE_IPV6);
+			parse_ipv6(ipv6_hdr, info);
+		}
+	} else {
+		info->ethertype = 0;
+		info->l4_len = 0;
+		info->l3_len = 0;
+		info->l4_proto = 0;
+	}
+
+	info->l2_len += RTE_ETHER_GTP_HLEN;
+}
+
 /* Parse a vxlan header */
 static void
 parse_vxlan(struct rte_udp_hdr *udp_hdr,
@@ -473,20 +551,27 @@ process_outer_cksums(void *outer_l3_hdr, struct testpmd_offload_info *info,
 		else
 			ipv4_hdr->hdr_checksum = rte_ipv4_cksum(ipv4_hdr);
 	} else
-		ol_flags |= PKT_TX_OUTER_IPV6;
+		ol_flags |= (PKT_TX_OUTER_IPV6 | PKT_TX_OUTER_IP_CKSUM);
 
 	if (info->outer_l4_proto != IPPROTO_UDP)
 		return ol_flags;
 
+	udp_hdr = (struct rte_udp_hdr *)
+		((char *)outer_l3_hdr + info->outer_l3_len);
+
 	/* Skip SW outer UDP checksum generation if HW supports it */
 	if (tx_offloads & DEV_TX_OFFLOAD_OUTER_UDP_CKSUM) {
+		if (info->outer_ethertype == _htons(RTE_ETHER_TYPE_IPV4))
+			udp_hdr->dgram_cksum
+				= rte_ipv4_phdr_cksum(ipv4_hdr, ol_flags);
+		else
+			udp_hdr->dgram_cksum
+				= rte_ipv6_phdr_cksum(ipv6_hdr, ol_flags);
+
 		ol_flags |= PKT_TX_OUTER_UDP_CKSUM;
 		return ol_flags;
 	}
 
-	udp_hdr = (struct rte_udp_hdr *)
-		((char *)outer_l3_hdr + info->outer_l3_len);
-
 	/* outer UDP checksum is done in software. In the other side, for
 	 * UDP tunneling, like VXLAN or Geneve, outer UDP checksum can be
 	 * set to zero.
@@ -679,6 +764,7 @@ pkt_copy_split(const struct rte_mbuf *pkt)
  *           UDP|TCP|SCTP
  *   Ether / (vlan) / outer IP|IP6 / outer UDP / VXLAN-GPE / IP|IP6 /
  *           UDP|TCP|SCTP
+ *   Ether / (vlan) / outer IP / outer UDP / GTP / IP|IP6 / UDP|TCP|SCTP
  *   Ether / (vlan) / outer IP|IP6 / GRE / Ether / IP|IP6 / UDP|TCP|SCTP
  *   Ether / (vlan) / outer IP|IP6 / GRE / IP|IP6 / UDP|TCP|SCTP
  *   Ether / (vlan) / outer IP|IP6 / IP|IP6 / UDP|TCP|SCTP
@@ -787,16 +873,22 @@ pkt_burst_checksum_forward(struct fwd_stream *fs)
 
 				udp_hdr = (struct rte_udp_hdr *)
 					((char *)l3_hdr + info.l3_len);
+				parse_gtp(udp_hdr, &info);
+				if (info.is_tunnel) {
+					tx_ol_flags |= PKT_TX_TUNNEL_GTP;
+					goto tunnel_update;
+				}
 				parse_vxlan_gpe(udp_hdr, &info);
 				if (info.is_tunnel) {
-					tx_ol_flags |= PKT_TX_TUNNEL_VXLAN_GPE;
-				} else {
-					parse_vxlan(udp_hdr, &info,
-						    m->packet_type);
-					if (info.is_tunnel)
-						tx_ol_flags |=
-							PKT_TX_TUNNEL_VXLAN;
+					tx_ol_flags |=
+						PKT_TX_TUNNEL_VXLAN_GPE;
+					goto tunnel_update;
 				}
+				parse_vxlan(udp_hdr, &info,
+					    m->packet_type);
+				if (info.is_tunnel)
+					tx_ol_flags |=
+					PKT_TX_TUNNEL_VXLAN;
 			} else if (info.l4_proto == IPPROTO_GRE) {
 				struct simple_gre_hdr *gre_hdr;
 
@@ -815,6 +907,7 @@ pkt_burst_checksum_forward(struct fwd_stream *fs)
 			}
 		}
 
+tunnel_update:
 		/* update l3_hdr and outer_l3_hdr if a tunnel was parsed */
 		if (info.is_tunnel) {
 			outer_l3_hdr = l3_hdr;
-- 
2.17.1


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

* Re: [dpdk-dev] [PATCH v3] app/testpmd: enable GTP header parse and Tx checksum offload
  2019-10-18 16:08   ` [dpdk-dev] [PATCH v3] " Ting Xu
@ 2019-10-18 18:49     ` Ferruh Yigit
  2019-10-21  2:28       ` Xu, Ting
  2019-10-21 12:29     ` [dpdk-dev] [PATCH v4] " Ting Xu
  1 sibling, 1 reply; 20+ messages in thread
From: Ferruh Yigit @ 2019-10-18 18:49 UTC (permalink / raw)
  To: Ting Xu, dev; +Cc: wenzhuo.lu, jingjing.wu, bernard.iremonger, qi.z.zhang

On 10/18/2019 5:08 PM, Ting Xu wrote:
> This patch enables testpmd to forward GTP packet in csum fwd mode.
> GTP header structure (without optional fields and extension header)
> and parser function are added. GTPU and GTPC packets are both
> supported, with respective UDP destination port and GTP message
> type.
> 
> Signed-off-by: Ting Xu <ting.xu@intel.com>
> 

<...>

> +/*
> + * Parse a GTP protocol header.
> + * No optional fields and next extension header type.
> + */
> +struct rte_gtp_hdr {
> +	uint8_t gtp_hdr_info;
> +	uint8_t msg_type;
> +	uint16_t msg_len;
> +	uint32_t teid;
> +} __attribute__((__packed__));
> +
> +/* GTP header length */
> +#define RTE_ETHER_GTP_HLEN \
> +	(sizeof(struct rte_udp_hdr) + sizeof(struct rte_gtp_hdr))
> +/* GTP next protocal type */
> +#define RTE_GTP_TYPE_IPV4 0x40
> +#define RTE_GTP_TYPE_IPV6 0x60
> +
> +static void
> +parse_gtp(struct rte_udp_hdr *udp_hdr,
> +	  struct testpmd_offload_info *info)
> +{
> +	struct rte_ipv4_hdr *ipv4_hdr;
> +	struct rte_ipv6_hdr *ipv6_hdr;
> +	struct rte_gtp_hdr *gtp_hdr;
> +	uint8_t gtp_len = sizeof(*gtp_hdr);
> +	uint8_t ip_ver;
> +	/* GTP destination port number */
> +	uint16_t gtpc_udp_port = 2123;
> +	uint16_t gtpu_udp_port = 2152;

What do you think about moving GTP related information into a gtp header file in
net library?

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

* Re: [dpdk-dev] [PATCH v3] app/testpmd: enable GTP header parse and Tx checksum offload
  2019-10-18 18:49     ` Ferruh Yigit
@ 2019-10-21  2:28       ` Xu, Ting
  0 siblings, 0 replies; 20+ messages in thread
From: Xu, Ting @ 2019-10-21  2:28 UTC (permalink / raw)
  To: Yigit, Ferruh, dev
  Cc: Lu, Wenzhuo, Wu, Jingjing, Iremonger, Bernard, Zhang, Qi Z, olivier.matz

Hi, Ferruh,

Thanks for your advice. I will move the header info into rte_ether.h. It could be better.

-----Original Message-----
From: Yigit, Ferruh 
Sent: Saturday, October 19, 2019 2:50 AM
To: Xu, Ting <ting.xu@intel.com>; dev@dpdk.org
Cc: Lu, Wenzhuo <wenzhuo.lu@intel.com>; Wu, Jingjing <jingjing.wu@intel.com>; Iremonger, Bernard <bernard.iremonger@intel.com>; Zhang, Qi Z <qi.z.zhang@intel.com>
Subject: Re: [dpdk-dev] [PATCH v3] app/testpmd: enable GTP header parse and Tx checksum offload

On 10/18/2019 5:08 PM, Ting Xu wrote:
> This patch enables testpmd to forward GTP packet in csum fwd mode.
> GTP header structure (without optional fields and extension header) 
> and parser function are added. GTPU and GTPC packets are both 
> supported, with respective UDP destination port and GTP message type.
> 
> Signed-off-by: Ting Xu <ting.xu@intel.com>
> 

<...>

> +/*
> + * Parse a GTP protocol header.
> + * No optional fields and next extension header type.
> + */
> +struct rte_gtp_hdr {
> +	uint8_t gtp_hdr_info;
> +	uint8_t msg_type;
> +	uint16_t msg_len;
> +	uint32_t teid;
> +} __attribute__((__packed__));
> +
> +/* GTP header length */
> +#define RTE_ETHER_GTP_HLEN \
> +	(sizeof(struct rte_udp_hdr) + sizeof(struct rte_gtp_hdr))
> +/* GTP next protocal type */
> +#define RTE_GTP_TYPE_IPV4 0x40
> +#define RTE_GTP_TYPE_IPV6 0x60
> +
> +static void
> +parse_gtp(struct rte_udp_hdr *udp_hdr,
> +	  struct testpmd_offload_info *info) {
> +	struct rte_ipv4_hdr *ipv4_hdr;
> +	struct rte_ipv6_hdr *ipv6_hdr;
> +	struct rte_gtp_hdr *gtp_hdr;
> +	uint8_t gtp_len = sizeof(*gtp_hdr);
> +	uint8_t ip_ver;
> +	/* GTP destination port number */
> +	uint16_t gtpc_udp_port = 2123;
> +	uint16_t gtpu_udp_port = 2152;

What do you think about moving GTP related information into a gtp header file in net library?

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

* Re: [dpdk-dev] [PATCH v4] app/testpmd: enable GTP header parse and Tx checksum offload
  2019-10-21 12:29     ` [dpdk-dev] [PATCH v4] " Ting Xu
@ 2019-10-21  9:28       ` Ferruh Yigit
  2019-10-21 10:52         ` Ferruh Yigit
  2019-10-22 12:29       ` [dpdk-dev] [PATCH v5] " Ting Xu
  1 sibling, 1 reply; 20+ messages in thread
From: Ferruh Yigit @ 2019-10-21  9:28 UTC (permalink / raw)
  To: Ting Xu, dev; +Cc: wenzhuo.lu, jingjing.wu, bernard.iremonger, olivier.matz

On 10/21/2019 1:29 PM, Ting Xu wrote:
> This patch enables testpmd to forward GTP packet in csum fwd mode.
> GTP header structure (without optional fields and extension header)
> and parser function are added. GTPU and GTPC packets are both
> supported, with respective UDP destination port and GTP message
> type.
> 
> Signed-off-by: Ting Xu <ting.xu@intel.com>
> 
> ---
> v4: Move GTP header defination to rte_ether.h
> v3: correct coding style issue.
> v2: modify commit log
> depend on patch: lib/mbuf: add GTP tunnel type flag.
> ---
>  app/test-pmd/csumonly.c    | 96 ++++++++++++++++++++++++++++++++++----
>  lib/librte_net/rte_ether.h | 23 +++++++++
>  2 files changed, 109 insertions(+), 10 deletions(-)

<...>

> --- a/lib/librte_net/rte_ether.h
> +++ b/lib/librte_net/rte_ether.h
> @@ -342,6 +342,29 @@ struct rte_vxlan_gpe_hdr {
>  			      sizeof(struct rte_vxlan_gpe_hdr))
>  /**< VXLAN-GPE tunnel header length. */
>  
> +/**
> + * Simplified GTP protocol header.
> + * Contains 8-bit flag, 8-bit message type,
> + * 16-bit message length, 32-bit TEID.
> + * No optional fields and next extension header.
> + */
> +struct rte_gtp_hdr {
> +	uint8_t gtp_hdr_info;
> +	uint8_t msg_type;
> +	uint16_t msg_len;
> +	uint32_t teid;
> +} __attribute__((__packed__));
> +
> +/* GTP header length */
> +#define RTE_ETHER_GTP_HLEN \
> +	(sizeof(struct rte_udp_hdr) + sizeof(struct rte_gtp_hdr))
> +/* GTP next protocal type */
> +#define RTE_GTP_TYPE_IPV4 0x40
> +#define RTE_GTP_TYPE_IPV6 0x60
> +/* GTP destination port number */
> +#define RTE_GTPC_UDP_PORT 2123
> +#define RTE_GTPU_UDP_PORT 2152
> +
>  /**
>   * Extract VLAN tag information into mbuf
>   *
> 

lgtm, @Oliver, any comment/objection on GTP part in rte_ether.h?

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

* Re: [dpdk-dev] [PATCH v4] app/testpmd: enable GTP header parse and Tx checksum offload
  2019-10-21  9:28       ` Ferruh Yigit
@ 2019-10-21 10:52         ` Ferruh Yigit
  2019-10-21 16:50           ` Olivier Matz
  0 siblings, 1 reply; 20+ messages in thread
From: Ferruh Yigit @ 2019-10-21 10:52 UTC (permalink / raw)
  To: Ting Xu, dev; +Cc: wenzhuo.lu, jingjing.wu, bernard.iremonger, olivier.matz

On 10/21/2019 10:28 AM, Ferruh Yigit wrote:
> On 10/21/2019 1:29 PM, Ting Xu wrote:
>> This patch enables testpmd to forward GTP packet in csum fwd mode.
>> GTP header structure (without optional fields and extension header)
>> and parser function are added. GTPU and GTPC packets are both
>> supported, with respective UDP destination port and GTP message
>> type.
>>
>> Signed-off-by: Ting Xu <ting.xu@intel.com>
>>
>> ---
>> v4: Move GTP header defination to rte_ether.h
>> v3: correct coding style issue.
>> v2: modify commit log
>> depend on patch: lib/mbuf: add GTP tunnel type flag.
>> ---
>>  app/test-pmd/csumonly.c    | 96 ++++++++++++++++++++++++++++++++++----
>>  lib/librte_net/rte_ether.h | 23 +++++++++
>>  2 files changed, 109 insertions(+), 10 deletions(-)
> 
> <...>
> 
>> --- a/lib/librte_net/rte_ether.h
>> +++ b/lib/librte_net/rte_ether.h
>> @@ -342,6 +342,29 @@ struct rte_vxlan_gpe_hdr {
>>  			      sizeof(struct rte_vxlan_gpe_hdr))
>>  /**< VXLAN-GPE tunnel header length. */
>>  
>> +/**
>> + * Simplified GTP protocol header.
>> + * Contains 8-bit flag, 8-bit message type,
>> + * 16-bit message length, 32-bit TEID.
>> + * No optional fields and next extension header.
>> + */
>> +struct rte_gtp_hdr {
>> +	uint8_t gtp_hdr_info;
>> +	uint8_t msg_type;
>> +	uint16_t msg_len;
>> +	uint32_t teid;
>> +} __attribute__((__packed__));
>> +
>> +/* GTP header length */
>> +#define RTE_ETHER_GTP_HLEN \
>> +	(sizeof(struct rte_udp_hdr) + sizeof(struct rte_gtp_hdr))
>> +/* GTP next protocal type */
>> +#define RTE_GTP_TYPE_IPV4 0x40
>> +#define RTE_GTP_TYPE_IPV6 0x60
>> +/* GTP destination port number */
>> +#define RTE_GTPC_UDP_PORT 2123
>> +#define RTE_GTPU_UDP_PORT 2152
>> +
>>  /**
>>   * Extract VLAN tag information into mbuf
>>   *
>>
> 
> lgtm, @Oliver, any comment/objection on GTP part in rte_ether.h?
> 

What about moving the defines to its own header, like rte_gtp? Is these defines
part of the ether?

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

* [dpdk-dev] [PATCH v4] app/testpmd: enable GTP header parse and Tx checksum offload
  2019-10-18 16:08   ` [dpdk-dev] [PATCH v3] " Ting Xu
  2019-10-18 18:49     ` Ferruh Yigit
@ 2019-10-21 12:29     ` Ting Xu
  2019-10-21  9:28       ` Ferruh Yigit
  2019-10-22 12:29       ` [dpdk-dev] [PATCH v5] " Ting Xu
  1 sibling, 2 replies; 20+ messages in thread
From: Ting Xu @ 2019-10-21 12:29 UTC (permalink / raw)
  To: dev; +Cc: wenzhuo.lu, jingjing.wu, bernard.iremonger, olivier.matz

This patch enables testpmd to forward GTP packet in csum fwd mode.
GTP header structure (without optional fields and extension header)
and parser function are added. GTPU and GTPC packets are both
supported, with respective UDP destination port and GTP message
type.

Signed-off-by: Ting Xu <ting.xu@intel.com>

---
v4: Move GTP header defination to rte_ether.h
v3: correct coding style issue.
v2: modify commit log
depend on patch: lib/mbuf: add GTP tunnel type flag.
---
 app/test-pmd/csumonly.c    | 96 ++++++++++++++++++++++++++++++++++----
 lib/librte_net/rte_ether.h | 23 +++++++++
 2 files changed, 109 insertions(+), 10 deletions(-)

diff --git a/app/test-pmd/csumonly.c b/app/test-pmd/csumonly.c
index e1cb7fb70..52adfffe1 100644
--- a/app/test-pmd/csumonly.c
+++ b/app/test-pmd/csumonly.c
@@ -179,6 +179,67 @@ parse_ethernet(struct rte_ether_hdr *eth_hdr, struct testpmd_offload_info *info)
 	}
 }
 
+/*
+ * Parse a GTP protocol header.
+ * No optional fields and next extension header type.
+ */
+static void
+parse_gtp(struct rte_udp_hdr *udp_hdr,
+	  struct testpmd_offload_info *info)
+{
+	struct rte_ipv4_hdr *ipv4_hdr;
+	struct rte_ipv6_hdr *ipv6_hdr;
+	struct rte_gtp_hdr *gtp_hdr;
+	uint8_t gtp_len = sizeof(*gtp_hdr);
+	uint8_t ip_ver;
+
+	/* Check udp destination port. */
+	if (udp_hdr->dst_port != _htons(RTE_GTPC_UDP_PORT) &&
+	    udp_hdr->src_port != _htons(RTE_GTPC_UDP_PORT) &&
+	    udp_hdr->dst_port != _htons(RTE_GTPU_UDP_PORT))
+		return;
+
+	info->is_tunnel = 1;
+	info->outer_ethertype = info->ethertype;
+	info->outer_l2_len = info->l2_len;
+	info->outer_l3_len = info->l3_len;
+	info->outer_l4_proto = info->l4_proto;
+	info->l2_len = 0;
+
+	gtp_hdr = (struct rte_gtp_hdr *)((char *)udp_hdr +
+		  sizeof(struct rte_udp_hdr));
+
+	/*
+	 * Check message type. If message type is 0xff, it is
+	 * a GTP data packet. If not, it is a GTP control packet
+	 */
+	if (gtp_hdr->msg_type == 0xff) {
+		ip_ver = *(uint8_t *)((char *)udp_hdr +
+			 sizeof(struct rte_udp_hdr) +
+			 sizeof(struct rte_gtp_hdr));
+		ip_ver = (ip_ver) & 0xf0;
+
+		if (ip_ver == RTE_GTP_TYPE_IPV4) {
+			ipv4_hdr = (struct rte_ipv4_hdr *)((char *)gtp_hdr +
+				   gtp_len);
+			info->ethertype = _htons(RTE_ETHER_TYPE_IPV4);
+			parse_ipv4(ipv4_hdr, info);
+		} else if (ip_ver == RTE_GTP_TYPE_IPV6) {
+			ipv6_hdr = (struct rte_ipv6_hdr *)((char *)gtp_hdr +
+				   gtp_len);
+			info->ethertype = _htons(RTE_ETHER_TYPE_IPV6);
+			parse_ipv6(ipv6_hdr, info);
+		}
+	} else {
+		info->ethertype = 0;
+		info->l4_len = 0;
+		info->l3_len = 0;
+		info->l4_proto = 0;
+	}
+
+	info->l2_len += RTE_ETHER_GTP_HLEN;
+}
+
 /* Parse a vxlan header */
 static void
 parse_vxlan(struct rte_udp_hdr *udp_hdr,
@@ -478,15 +539,22 @@ process_outer_cksums(void *outer_l3_hdr, struct testpmd_offload_info *info,
 	if (info->outer_l4_proto != IPPROTO_UDP)
 		return ol_flags;
 
+	udp_hdr = (struct rte_udp_hdr *)
+		((char *)outer_l3_hdr + info->outer_l3_len);
+
 	/* Skip SW outer UDP checksum generation if HW supports it */
 	if (tx_offloads & DEV_TX_OFFLOAD_OUTER_UDP_CKSUM) {
+		if (info->outer_ethertype == _htons(RTE_ETHER_TYPE_IPV4))
+			udp_hdr->dgram_cksum
+				= rte_ipv4_phdr_cksum(ipv4_hdr, ol_flags);
+		else
+			udp_hdr->dgram_cksum
+				= rte_ipv6_phdr_cksum(ipv6_hdr, ol_flags);
+
 		ol_flags |= PKT_TX_OUTER_UDP_CKSUM;
 		return ol_flags;
 	}
 
-	udp_hdr = (struct rte_udp_hdr *)
-		((char *)outer_l3_hdr + info->outer_l3_len);
-
 	/* outer UDP checksum is done in software. In the other side, for
 	 * UDP tunneling, like VXLAN or Geneve, outer UDP checksum can be
 	 * set to zero.
@@ -679,6 +747,7 @@ pkt_copy_split(const struct rte_mbuf *pkt)
  *           UDP|TCP|SCTP
  *   Ether / (vlan) / outer IP|IP6 / outer UDP / VXLAN-GPE / IP|IP6 /
  *           UDP|TCP|SCTP
+ *   Ether / (vlan) / outer IP / outer UDP / GTP / IP|IP6 / UDP|TCP|SCTP
  *   Ether / (vlan) / outer IP|IP6 / GRE / Ether / IP|IP6 / UDP|TCP|SCTP
  *   Ether / (vlan) / outer IP|IP6 / GRE / IP|IP6 / UDP|TCP|SCTP
  *   Ether / (vlan) / outer IP|IP6 / IP|IP6 / UDP|TCP|SCTP
@@ -787,16 +856,22 @@ pkt_burst_checksum_forward(struct fwd_stream *fs)
 
 				udp_hdr = (struct rte_udp_hdr *)
 					((char *)l3_hdr + info.l3_len);
+				parse_gtp(udp_hdr, &info);
+				if (info.is_tunnel) {
+					tx_ol_flags |= PKT_TX_TUNNEL_GTP;
+					goto tunnel_update;
+				}
 				parse_vxlan_gpe(udp_hdr, &info);
 				if (info.is_tunnel) {
-					tx_ol_flags |= PKT_TX_TUNNEL_VXLAN_GPE;
-				} else {
-					parse_vxlan(udp_hdr, &info,
-						    m->packet_type);
-					if (info.is_tunnel)
-						tx_ol_flags |=
-							PKT_TX_TUNNEL_VXLAN;
+					tx_ol_flags |=
+						PKT_TX_TUNNEL_VXLAN_GPE;
+					goto tunnel_update;
 				}
+				parse_vxlan(udp_hdr, &info,
+					    m->packet_type);
+				if (info.is_tunnel)
+					tx_ol_flags |=
+						PKT_TX_TUNNEL_VXLAN;
 			} else if (info.l4_proto == IPPROTO_GRE) {
 				struct simple_gre_hdr *gre_hdr;
 
@@ -815,6 +890,7 @@ pkt_burst_checksum_forward(struct fwd_stream *fs)
 			}
 		}
 
+tunnel_update:
 		/* update l3_hdr and outer_l3_hdr if a tunnel was parsed */
 		if (info.is_tunnel) {
 			outer_l3_hdr = l3_hdr;
diff --git a/lib/librte_net/rte_ether.h b/lib/librte_net/rte_ether.h
index aa6eff037..33ad347d8 100644
--- a/lib/librte_net/rte_ether.h
+++ b/lib/librte_net/rte_ether.h
@@ -342,6 +342,29 @@ struct rte_vxlan_gpe_hdr {
 			      sizeof(struct rte_vxlan_gpe_hdr))
 /**< VXLAN-GPE tunnel header length. */
 
+/**
+ * Simplified GTP protocol header.
+ * Contains 8-bit flag, 8-bit message type,
+ * 16-bit message length, 32-bit TEID.
+ * No optional fields and next extension header.
+ */
+struct rte_gtp_hdr {
+	uint8_t gtp_hdr_info;
+	uint8_t msg_type;
+	uint16_t msg_len;
+	uint32_t teid;
+} __attribute__((__packed__));
+
+/* GTP header length */
+#define RTE_ETHER_GTP_HLEN \
+	(sizeof(struct rte_udp_hdr) + sizeof(struct rte_gtp_hdr))
+/* GTP next protocal type */
+#define RTE_GTP_TYPE_IPV4 0x40
+#define RTE_GTP_TYPE_IPV6 0x60
+/* GTP destination port number */
+#define RTE_GTPC_UDP_PORT 2123
+#define RTE_GTPU_UDP_PORT 2152
+
 /**
  * Extract VLAN tag information into mbuf
  *
-- 
2.17.1


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

* Re: [dpdk-dev] [PATCH v4] app/testpmd: enable GTP header parse and Tx checksum offload
  2019-10-21 10:52         ` Ferruh Yigit
@ 2019-10-21 16:50           ` Olivier Matz
  2019-10-22  5:34             ` Xu, Ting
  0 siblings, 1 reply; 20+ messages in thread
From: Olivier Matz @ 2019-10-21 16:50 UTC (permalink / raw)
  To: Ferruh Yigit; +Cc: Ting Xu, dev, wenzhuo.lu, jingjing.wu, bernard.iremonger

On Mon, Oct 21, 2019 at 11:52:46AM +0100, Ferruh Yigit wrote:
> On 10/21/2019 10:28 AM, Ferruh Yigit wrote:
> > On 10/21/2019 1:29 PM, Ting Xu wrote:
> >> This patch enables testpmd to forward GTP packet in csum fwd mode.
> >> GTP header structure (without optional fields and extension header)
> >> and parser function are added. GTPU and GTPC packets are both
> >> supported, with respective UDP destination port and GTP message
> >> type.
> >>
> >> Signed-off-by: Ting Xu <ting.xu@intel.com>
> >>
> >> ---
> >> v4: Move GTP header defination to rte_ether.h
> >> v3: correct coding style issue.
> >> v2: modify commit log
> >> depend on patch: lib/mbuf: add GTP tunnel type flag.
> >> ---
> >>  app/test-pmd/csumonly.c    | 96 ++++++++++++++++++++++++++++++++++----
> >>  lib/librte_net/rte_ether.h | 23 +++++++++
> >>  2 files changed, 109 insertions(+), 10 deletions(-)
> > 
> > <...>
> > 
> >> --- a/lib/librte_net/rte_ether.h
> >> +++ b/lib/librte_net/rte_ether.h
> >> @@ -342,6 +342,29 @@ struct rte_vxlan_gpe_hdr {
> >>  			      sizeof(struct rte_vxlan_gpe_hdr))
> >>  /**< VXLAN-GPE tunnel header length. */
> >>  
> >> +/**
> >> + * Simplified GTP protocol header.
> >> + * Contains 8-bit flag, 8-bit message type,
> >> + * 16-bit message length, 32-bit TEID.
> >> + * No optional fields and next extension header.
> >> + */
> >> +struct rte_gtp_hdr {
> >> +	uint8_t gtp_hdr_info;
> >> +	uint8_t msg_type;
> >> +	uint16_t msg_len;
> >> +	uint32_t teid;
> >> +} __attribute__((__packed__));
> >> +
> >> +/* GTP header length */
> >> +#define RTE_ETHER_GTP_HLEN \
> >> +	(sizeof(struct rte_udp_hdr) + sizeof(struct rte_gtp_hdr))
> >> +/* GTP next protocal type */
> >> +#define RTE_GTP_TYPE_IPV4 0x40
> >> +#define RTE_GTP_TYPE_IPV6 0x60
> >> +/* GTP destination port number */
> >> +#define RTE_GTPC_UDP_PORT 2123
> >> +#define RTE_GTPU_UDP_PORT 2152
> >> +
> >>  /**
> >>   * Extract VLAN tag information into mbuf
> >>   *
> >>
> > 
> > lgtm, @Oliver, any comment/objection on GTP part in rte_ether.h?
> > 
> 
> What about moving the defines to its own header, like rte_gtp? Is these defines
> part of the ether?

+1

I also think it deserves its own file.


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

* Re: [dpdk-dev] [PATCH v4] app/testpmd: enable GTP header parse and Tx checksum offload
  2019-10-21 16:50           ` Olivier Matz
@ 2019-10-22  5:34             ` Xu, Ting
  0 siblings, 0 replies; 20+ messages in thread
From: Xu, Ting @ 2019-10-22  5:34 UTC (permalink / raw)
  To: Olivier Matz, Yigit, Ferruh
  Cc: dev, Lu, Wenzhuo, Wu,  Jingjing, Iremonger, Bernard

Hi, Ferruh, Olivier,

Thanks for your advice. I think I misunderstood the comments in the last commit.
This time I move the GTP header definition in the new file rte_gtp.h. Hope it would be better.

Thanks.

-----Original Message-----
From: Olivier Matz [mailto:olivier.matz@6wind.com] 
Sent: Tuesday, October 22, 2019 12:51 AM
To: Yigit, Ferruh <ferruh.yigit@intel.com>
Cc: Xu, Ting <ting.xu@intel.com>; dev@dpdk.org; Lu, Wenzhuo <wenzhuo.lu@intel.com>; Wu, Jingjing <jingjing.wu@intel.com>; Iremonger, Bernard <bernard.iremonger@intel.com>
Subject: Re: [dpdk-dev] [PATCH v4] app/testpmd: enable GTP header parse and Tx checksum offload

On Mon, Oct 21, 2019 at 11:52:46AM +0100, Ferruh Yigit wrote:
> On 10/21/2019 10:28 AM, Ferruh Yigit wrote:
> > On 10/21/2019 1:29 PM, Ting Xu wrote:
> >> This patch enables testpmd to forward GTP packet in csum fwd mode.
> >> GTP header structure (without optional fields and extension header) 
> >> and parser function are added. GTPU and GTPC packets are both 
> >> supported, with respective UDP destination port and GTP message 
> >> type.
> >>
> >> Signed-off-by: Ting Xu <ting.xu@intel.com>
> >>
> >> ---
> >> v4: Move GTP header defination to rte_ether.h
> >> v3: correct coding style issue.
> >> v2: modify commit log
> >> depend on patch: lib/mbuf: add GTP tunnel type flag.
> >> ---
> >>  app/test-pmd/csumonly.c    | 96 ++++++++++++++++++++++++++++++++++----
> >>  lib/librte_net/rte_ether.h | 23 +++++++++
> >>  2 files changed, 109 insertions(+), 10 deletions(-)
> > 
> > <...>
> > 
> >> --- a/lib/librte_net/rte_ether.h
> >> +++ b/lib/librte_net/rte_ether.h
> >> @@ -342,6 +342,29 @@ struct rte_vxlan_gpe_hdr {
> >>  			      sizeof(struct rte_vxlan_gpe_hdr))  /**< VXLAN-GPE tunnel 
> >> header length. */
> >>  
> >> +/**
> >> + * Simplified GTP protocol header.
> >> + * Contains 8-bit flag, 8-bit message type,
> >> + * 16-bit message length, 32-bit TEID.
> >> + * No optional fields and next extension header.
> >> + */
> >> +struct rte_gtp_hdr {
> >> +	uint8_t gtp_hdr_info;
> >> +	uint8_t msg_type;
> >> +	uint16_t msg_len;
> >> +	uint32_t teid;
> >> +} __attribute__((__packed__));
> >> +
> >> +/* GTP header length */
> >> +#define RTE_ETHER_GTP_HLEN \
> >> +	(sizeof(struct rte_udp_hdr) + sizeof(struct rte_gtp_hdr))
> >> +/* GTP next protocal type */
> >> +#define RTE_GTP_TYPE_IPV4 0x40
> >> +#define RTE_GTP_TYPE_IPV6 0x60
> >> +/* GTP destination port number */
> >> +#define RTE_GTPC_UDP_PORT 2123
> >> +#define RTE_GTPU_UDP_PORT 2152
> >> +
> >>  /**
> >>   * Extract VLAN tag information into mbuf
> >>   *
> >>
> > 
> > lgtm, @Oliver, any comment/objection on GTP part in rte_ether.h?
> > 
> 
> What about moving the defines to its own header, like rte_gtp? Is 
> these defines part of the ether?

+1

I also think it deserves its own file.


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

* Re: [dpdk-dev] [PATCH v5] app/testpmd: enable GTP header parse and Tx checksum offload
  2019-10-22 12:29       ` [dpdk-dev] [PATCH v5] " Ting Xu
@ 2019-10-22  8:14         ` Ferruh Yigit
  2019-10-22 16:26         ` [dpdk-dev] [PATCH v6] " Ting Xu
  1 sibling, 0 replies; 20+ messages in thread
From: Ferruh Yigit @ 2019-10-22  8:14 UTC (permalink / raw)
  To: Ting Xu, dev; +Cc: wenzhuo.lu, jingjing.wu, bernard.iremonger, olivier.matz

On 10/22/2019 1:29 PM, Ting Xu wrote:
> This patch enables testpmd to forward GTP packet in csum fwd mode.
> A GTP header structure (without optional fields and extension header)
> is defined in new rte_gtp.h. A parser function in testpmd is added.
> GTPU and GTPC packets are both supported, with respective UDP
> destination port and GTP message type.
> 
> Signed-off-by: Ting Xu <ting.xu@intel.com>
> 
> ---
> v5: Create rte_gtp.h and move GTP header defination
> to it.
> v4: Move GTP header defination to rte_ether.h
> v3: correct coding style issue.
> v2: modify commit log
> depend on patch: lib/mbuf: add GTP tunnel type flag.
> ---
>  app/test-pmd/csumonly.c  | 97 +++++++++++++++++++++++++++++++++++-----
>  lib/librte_net/Makefile  |  2 +-
>  lib/librte_net/rte_gtp.h | 52 +++++++++++++++++++++

Thanks Ting,

Can you also please this new header to 'doc/api/doxy-api-index.md' so that it
can be part of API documentation, and can you please be sure the header file
doxygen documentation is complete?

Thanks,
ferruh

>  3 files changed, 140 insertions(+), 11 deletions(-)
>  create mode 100644 lib/librte_net/rte_gtp.h

<...>


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

* [dpdk-dev] [PATCH v5] app/testpmd: enable GTP header parse and Tx checksum offload
  2019-10-21 12:29     ` [dpdk-dev] [PATCH v4] " Ting Xu
  2019-10-21  9:28       ` Ferruh Yigit
@ 2019-10-22 12:29       ` Ting Xu
  2019-10-22  8:14         ` Ferruh Yigit
  2019-10-22 16:26         ` [dpdk-dev] [PATCH v6] " Ting Xu
  1 sibling, 2 replies; 20+ messages in thread
From: Ting Xu @ 2019-10-22 12:29 UTC (permalink / raw)
  To: dev; +Cc: wenzhuo.lu, jingjing.wu, bernard.iremonger, olivier.matz

This patch enables testpmd to forward GTP packet in csum fwd mode.
A GTP header structure (without optional fields and extension header)
is defined in new rte_gtp.h. A parser function in testpmd is added.
GTPU and GTPC packets are both supported, with respective UDP
destination port and GTP message type.

Signed-off-by: Ting Xu <ting.xu@intel.com>

---
v5: Create rte_gtp.h and move GTP header defination
to it.
v4: Move GTP header defination to rte_ether.h
v3: correct coding style issue.
v2: modify commit log
depend on patch: lib/mbuf: add GTP tunnel type flag.
---
 app/test-pmd/csumonly.c  | 97 +++++++++++++++++++++++++++++++++++-----
 lib/librte_net/Makefile  |  2 +-
 lib/librte_net/rte_gtp.h | 52 +++++++++++++++++++++
 3 files changed, 140 insertions(+), 11 deletions(-)
 create mode 100644 lib/librte_net/rte_gtp.h

diff --git a/app/test-pmd/csumonly.c b/app/test-pmd/csumonly.c
index e1cb7fb70..c3fd5e17d 100644
--- a/app/test-pmd/csumonly.c
+++ b/app/test-pmd/csumonly.c
@@ -36,6 +36,7 @@
 #include <rte_tcp.h>
 #include <rte_udp.h>
 #include <rte_sctp.h>
+#include <rte_gtp.h>
 #include <rte_prefetch.h>
 #include <rte_string_fns.h>
 #include <rte_flow.h>
@@ -179,6 +180,67 @@ parse_ethernet(struct rte_ether_hdr *eth_hdr, struct testpmd_offload_info *info)
 	}
 }
 
+/*
+ * Parse a GTP protocol header.
+ * No optional fields and next extension header type.
+ */
+static void
+parse_gtp(struct rte_udp_hdr *udp_hdr,
+	  struct testpmd_offload_info *info)
+{
+	struct rte_ipv4_hdr *ipv4_hdr;
+	struct rte_ipv6_hdr *ipv6_hdr;
+	struct rte_gtp_hdr *gtp_hdr;
+	uint8_t gtp_len = sizeof(*gtp_hdr);
+	uint8_t ip_ver;
+
+	/* Check udp destination port. */
+	if (udp_hdr->dst_port != _htons(RTE_GTPC_UDP_PORT) &&
+	    udp_hdr->src_port != _htons(RTE_GTPC_UDP_PORT) &&
+	    udp_hdr->dst_port != _htons(RTE_GTPU_UDP_PORT))
+		return;
+
+	info->is_tunnel = 1;
+	info->outer_ethertype = info->ethertype;
+	info->outer_l2_len = info->l2_len;
+	info->outer_l3_len = info->l3_len;
+	info->outer_l4_proto = info->l4_proto;
+	info->l2_len = 0;
+
+	gtp_hdr = (struct rte_gtp_hdr *)((char *)udp_hdr +
+		  sizeof(struct rte_udp_hdr));
+
+	/*
+	 * Check message type. If message type is 0xff, it is
+	 * a GTP data packet. If not, it is a GTP control packet
+	 */
+	if (gtp_hdr->msg_type == 0xff) {
+		ip_ver = *(uint8_t *)((char *)udp_hdr +
+			 sizeof(struct rte_udp_hdr) +
+			 sizeof(struct rte_gtp_hdr));
+		ip_ver = (ip_ver) & 0xf0;
+
+		if (ip_ver == RTE_GTP_TYPE_IPV4) {
+			ipv4_hdr = (struct rte_ipv4_hdr *)((char *)gtp_hdr +
+				   gtp_len);
+			info->ethertype = _htons(RTE_ETHER_TYPE_IPV4);
+			parse_ipv4(ipv4_hdr, info);
+		} else if (ip_ver == RTE_GTP_TYPE_IPV6) {
+			ipv6_hdr = (struct rte_ipv6_hdr *)((char *)gtp_hdr +
+				   gtp_len);
+			info->ethertype = _htons(RTE_ETHER_TYPE_IPV6);
+			parse_ipv6(ipv6_hdr, info);
+		}
+	} else {
+		info->ethertype = 0;
+		info->l4_len = 0;
+		info->l3_len = 0;
+		info->l4_proto = 0;
+	}
+
+	info->l2_len += RTE_ETHER_GTP_HLEN;
+}
+
 /* Parse a vxlan header */
 static void
 parse_vxlan(struct rte_udp_hdr *udp_hdr,
@@ -478,15 +540,22 @@ process_outer_cksums(void *outer_l3_hdr, struct testpmd_offload_info *info,
 	if (info->outer_l4_proto != IPPROTO_UDP)
 		return ol_flags;
 
+	udp_hdr = (struct rte_udp_hdr *)
+		((char *)outer_l3_hdr + info->outer_l3_len);
+
 	/* Skip SW outer UDP checksum generation if HW supports it */
 	if (tx_offloads & DEV_TX_OFFLOAD_OUTER_UDP_CKSUM) {
+		if (info->outer_ethertype == _htons(RTE_ETHER_TYPE_IPV4))
+			udp_hdr->dgram_cksum
+				= rte_ipv4_phdr_cksum(ipv4_hdr, ol_flags);
+		else
+			udp_hdr->dgram_cksum
+				= rte_ipv6_phdr_cksum(ipv6_hdr, ol_flags);
+
 		ol_flags |= PKT_TX_OUTER_UDP_CKSUM;
 		return ol_flags;
 	}
 
-	udp_hdr = (struct rte_udp_hdr *)
-		((char *)outer_l3_hdr + info->outer_l3_len);
-
 	/* outer UDP checksum is done in software. In the other side, for
 	 * UDP tunneling, like VXLAN or Geneve, outer UDP checksum can be
 	 * set to zero.
@@ -679,6 +748,7 @@ pkt_copy_split(const struct rte_mbuf *pkt)
  *           UDP|TCP|SCTP
  *   Ether / (vlan) / outer IP|IP6 / outer UDP / VXLAN-GPE / IP|IP6 /
  *           UDP|TCP|SCTP
+ *   Ether / (vlan) / outer IP / outer UDP / GTP / IP|IP6 / UDP|TCP|SCTP
  *   Ether / (vlan) / outer IP|IP6 / GRE / Ether / IP|IP6 / UDP|TCP|SCTP
  *   Ether / (vlan) / outer IP|IP6 / GRE / IP|IP6 / UDP|TCP|SCTP
  *   Ether / (vlan) / outer IP|IP6 / IP|IP6 / UDP|TCP|SCTP
@@ -787,16 +857,22 @@ pkt_burst_checksum_forward(struct fwd_stream *fs)
 
 				udp_hdr = (struct rte_udp_hdr *)
 					((char *)l3_hdr + info.l3_len);
+				parse_gtp(udp_hdr, &info);
+				if (info.is_tunnel) {
+					tx_ol_flags |= PKT_TX_TUNNEL_GTP;
+					goto tunnel_update;
+				}
 				parse_vxlan_gpe(udp_hdr, &info);
 				if (info.is_tunnel) {
-					tx_ol_flags |= PKT_TX_TUNNEL_VXLAN_GPE;
-				} else {
-					parse_vxlan(udp_hdr, &info,
-						    m->packet_type);
-					if (info.is_tunnel)
-						tx_ol_flags |=
-							PKT_TX_TUNNEL_VXLAN;
+					tx_ol_flags |=
+						PKT_TX_TUNNEL_VXLAN_GPE;
+					goto tunnel_update;
 				}
+				parse_vxlan(udp_hdr, &info,
+					    m->packet_type);
+				if (info.is_tunnel)
+					tx_ol_flags |=
+						PKT_TX_TUNNEL_VXLAN;
 			} else if (info.l4_proto == IPPROTO_GRE) {
 				struct simple_gre_hdr *gre_hdr;
 
@@ -815,6 +891,7 @@ pkt_burst_checksum_forward(struct fwd_stream *fs)
 			}
 		}
 
+tunnel_update:
 		/* update l3_hdr and outer_l3_hdr if a tunnel was parsed */
 		if (info.is_tunnel) {
 			outer_l3_hdr = l3_hdr;
diff --git a/lib/librte_net/Makefile b/lib/librte_net/Makefile
index 1244c9fd5..4ad02aee0 100644
--- a/lib/librte_net/Makefile
+++ b/lib/librte_net/Makefile
@@ -20,7 +20,7 @@ SRCS-$(CONFIG_RTE_LIBRTE_NET) += rte_arp.c
 # install includes
 SYMLINK-$(CONFIG_RTE_LIBRTE_NET)-include := rte_ip.h rte_tcp.h rte_udp.h rte_esp.h
 SYMLINK-$(CONFIG_RTE_LIBRTE_NET)-include += rte_sctp.h rte_icmp.h rte_arp.h
-SYMLINK-$(CONFIG_RTE_LIBRTE_NET)-include += rte_ether.h rte_gre.h rte_net.h
+SYMLINK-$(CONFIG_RTE_LIBRTE_NET)-include += rte_ether.h rte_gre.h rte_gtp.h rte_net.h
 SYMLINK-$(CONFIG_RTE_LIBRTE_NET)-include += rte_net_crc.h rte_mpls.h
 
 include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/lib/librte_net/rte_gtp.h b/lib/librte_net/rte_gtp.h
new file mode 100644
index 000000000..8fe51de14
--- /dev/null
+++ b/lib/librte_net/rte_gtp.h
@@ -0,0 +1,52 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 1982, 1986, 1990, 1993
+ *      The Regents of the University of California.
+ * Copyright(c) 2010-2014 Intel Corporation.
+ * All rights reserved.
+ */
+
+#ifndef _RTE_GTP_H_
+#define _RTE_GTP_H_
+
+/**
+ * @file
+ *
+ * GTP-related defines
+ */
+
+#include <stdint.h>
+#include <rte_byteorder.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Simplified GTP protocol header.
+ * Contains 8-bit flag, 8-bit message type,
+ * 16-bit message length, 32-bit TEID.
+ * No optional fields and next extension header.
+ */
+struct rte_gtp_hdr {
+	uint8_t gtp_hdr_info; /**< GTP header info. */
+	uint8_t msg_type;     /**< GTP message type. */
+	uint16_t msg_len;     /**< Total message length. */
+	uint32_t teid;        /**< Tunnel endpoint ID */
+} __attribute__((__packed__));
+
+/* GTP header length */
+#define RTE_ETHER_GTP_HLEN \
+	(sizeof(struct rte_udp_hdr) + sizeof(struct rte_gtp_hdr))
+/* GTP next protocal type */
+#define RTE_GTP_TYPE_IPV4 0x40
+#define RTE_GTP_TYPE_IPV6 0x60
+/* GTP destination port number */
+#define RTE_GTPC_UDP_PORT 2123
+#define RTE_GTPU_UDP_PORT 2152
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* RTE_GTP_H_ */
+
-- 
2.17.1


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

* Re: [dpdk-dev] [PATCH v6] app/testpmd: enable GTP header parse and Tx checksum offload
  2019-10-22 16:26         ` [dpdk-dev] [PATCH v6] " Ting Xu
@ 2019-10-22 15:45           ` Ferruh Yigit
  2019-10-23 17:23             ` Ferruh Yigit
  2019-10-25 22:49           ` Thomas Monjalon
  1 sibling, 1 reply; 20+ messages in thread
From: Ferruh Yigit @ 2019-10-22 15:45 UTC (permalink / raw)
  To: Ting Xu, dev; +Cc: wenzhuo.lu, jingjing.wu, bernard.iremonger, olivier.matz

On 10/22/2019 5:26 PM, Ting Xu wrote:
> This patch enables testpmd to forward GTP packet in csum fwd mode.
> A GTP header structure (without optional fields and extension header)
> is defined in new rte_gtp.h. A parser function in testpmd is added.
> GTPU and GTPC packets are both supported, with respective UDP
> destination port and GTP message type.
> 
> Signed-off-by: Ting Xu <ting.xu@intel.com>
> 
> ---
> v6: complete doxygen documentation.
> v5: create rte_gtp.h and move GTP header definition
> to it.
> v4: move GTP header definition to rte_ether.h
> v3: correct coding style issue.
> v2: modify commit log
> 
> depend on patch: lib/mbuf: add GTP tunnel type flag.

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

Will wait mbuf patch to be applied to get the patch.


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

* [dpdk-dev] [PATCH v6] app/testpmd: enable GTP header parse and Tx checksum offload
  2019-10-22 12:29       ` [dpdk-dev] [PATCH v5] " Ting Xu
  2019-10-22  8:14         ` Ferruh Yigit
@ 2019-10-22 16:26         ` Ting Xu
  2019-10-22 15:45           ` Ferruh Yigit
  2019-10-25 22:49           ` Thomas Monjalon
  1 sibling, 2 replies; 20+ messages in thread
From: Ting Xu @ 2019-10-22 16:26 UTC (permalink / raw)
  To: dev
  Cc: wenzhuo.lu, jingjing.wu, bernard.iremonger, olivier.matz, ferruh.yigit

This patch enables testpmd to forward GTP packet in csum fwd mode.
A GTP header structure (without optional fields and extension header)
is defined in new rte_gtp.h. A parser function in testpmd is added.
GTPU and GTPC packets are both supported, with respective UDP
destination port and GTP message type.

Signed-off-by: Ting Xu <ting.xu@intel.com>

---
v6: complete doxygen documentation.
v5: create rte_gtp.h and move GTP header definition
to it.
v4: move GTP header definition to rte_ether.h
v3: correct coding style issue.
v2: modify commit log

depend on patch: lib/mbuf: add GTP tunnel type flag.
---
 app/test-pmd/csumonly.c   | 97 +++++++++++++++++++++++++++++++++++----
 doc/api/doxy-api-index.md |  1 +
 lib/librte_net/Makefile   |  2 +-
 lib/librte_net/rte_gtp.h  | 52 +++++++++++++++++++++
 4 files changed, 141 insertions(+), 11 deletions(-)
 create mode 100644 lib/librte_net/rte_gtp.h

diff --git a/app/test-pmd/csumonly.c b/app/test-pmd/csumonly.c
index e1cb7fb70..c3fd5e17d 100644
--- a/app/test-pmd/csumonly.c
+++ b/app/test-pmd/csumonly.c
@@ -36,6 +36,7 @@
 #include <rte_tcp.h>
 #include <rte_udp.h>
 #include <rte_sctp.h>
+#include <rte_gtp.h>
 #include <rte_prefetch.h>
 #include <rte_string_fns.h>
 #include <rte_flow.h>
@@ -179,6 +180,67 @@ parse_ethernet(struct rte_ether_hdr *eth_hdr, struct testpmd_offload_info *info)
 	}
 }
 
+/*
+ * Parse a GTP protocol header.
+ * No optional fields and next extension header type.
+ */
+static void
+parse_gtp(struct rte_udp_hdr *udp_hdr,
+	  struct testpmd_offload_info *info)
+{
+	struct rte_ipv4_hdr *ipv4_hdr;
+	struct rte_ipv6_hdr *ipv6_hdr;
+	struct rte_gtp_hdr *gtp_hdr;
+	uint8_t gtp_len = sizeof(*gtp_hdr);
+	uint8_t ip_ver;
+
+	/* Check udp destination port. */
+	if (udp_hdr->dst_port != _htons(RTE_GTPC_UDP_PORT) &&
+	    udp_hdr->src_port != _htons(RTE_GTPC_UDP_PORT) &&
+	    udp_hdr->dst_port != _htons(RTE_GTPU_UDP_PORT))
+		return;
+
+	info->is_tunnel = 1;
+	info->outer_ethertype = info->ethertype;
+	info->outer_l2_len = info->l2_len;
+	info->outer_l3_len = info->l3_len;
+	info->outer_l4_proto = info->l4_proto;
+	info->l2_len = 0;
+
+	gtp_hdr = (struct rte_gtp_hdr *)((char *)udp_hdr +
+		  sizeof(struct rte_udp_hdr));
+
+	/*
+	 * Check message type. If message type is 0xff, it is
+	 * a GTP data packet. If not, it is a GTP control packet
+	 */
+	if (gtp_hdr->msg_type == 0xff) {
+		ip_ver = *(uint8_t *)((char *)udp_hdr +
+			 sizeof(struct rte_udp_hdr) +
+			 sizeof(struct rte_gtp_hdr));
+		ip_ver = (ip_ver) & 0xf0;
+
+		if (ip_ver == RTE_GTP_TYPE_IPV4) {
+			ipv4_hdr = (struct rte_ipv4_hdr *)((char *)gtp_hdr +
+				   gtp_len);
+			info->ethertype = _htons(RTE_ETHER_TYPE_IPV4);
+			parse_ipv4(ipv4_hdr, info);
+		} else if (ip_ver == RTE_GTP_TYPE_IPV6) {
+			ipv6_hdr = (struct rte_ipv6_hdr *)((char *)gtp_hdr +
+				   gtp_len);
+			info->ethertype = _htons(RTE_ETHER_TYPE_IPV6);
+			parse_ipv6(ipv6_hdr, info);
+		}
+	} else {
+		info->ethertype = 0;
+		info->l4_len = 0;
+		info->l3_len = 0;
+		info->l4_proto = 0;
+	}
+
+	info->l2_len += RTE_ETHER_GTP_HLEN;
+}
+
 /* Parse a vxlan header */
 static void
 parse_vxlan(struct rte_udp_hdr *udp_hdr,
@@ -478,15 +540,22 @@ process_outer_cksums(void *outer_l3_hdr, struct testpmd_offload_info *info,
 	if (info->outer_l4_proto != IPPROTO_UDP)
 		return ol_flags;
 
+	udp_hdr = (struct rte_udp_hdr *)
+		((char *)outer_l3_hdr + info->outer_l3_len);
+
 	/* Skip SW outer UDP checksum generation if HW supports it */
 	if (tx_offloads & DEV_TX_OFFLOAD_OUTER_UDP_CKSUM) {
+		if (info->outer_ethertype == _htons(RTE_ETHER_TYPE_IPV4))
+			udp_hdr->dgram_cksum
+				= rte_ipv4_phdr_cksum(ipv4_hdr, ol_flags);
+		else
+			udp_hdr->dgram_cksum
+				= rte_ipv6_phdr_cksum(ipv6_hdr, ol_flags);
+
 		ol_flags |= PKT_TX_OUTER_UDP_CKSUM;
 		return ol_flags;
 	}
 
-	udp_hdr = (struct rte_udp_hdr *)
-		((char *)outer_l3_hdr + info->outer_l3_len);
-
 	/* outer UDP checksum is done in software. In the other side, for
 	 * UDP tunneling, like VXLAN or Geneve, outer UDP checksum can be
 	 * set to zero.
@@ -679,6 +748,7 @@ pkt_copy_split(const struct rte_mbuf *pkt)
  *           UDP|TCP|SCTP
  *   Ether / (vlan) / outer IP|IP6 / outer UDP / VXLAN-GPE / IP|IP6 /
  *           UDP|TCP|SCTP
+ *   Ether / (vlan) / outer IP / outer UDP / GTP / IP|IP6 / UDP|TCP|SCTP
  *   Ether / (vlan) / outer IP|IP6 / GRE / Ether / IP|IP6 / UDP|TCP|SCTP
  *   Ether / (vlan) / outer IP|IP6 / GRE / IP|IP6 / UDP|TCP|SCTP
  *   Ether / (vlan) / outer IP|IP6 / IP|IP6 / UDP|TCP|SCTP
@@ -787,16 +857,22 @@ pkt_burst_checksum_forward(struct fwd_stream *fs)
 
 				udp_hdr = (struct rte_udp_hdr *)
 					((char *)l3_hdr + info.l3_len);
+				parse_gtp(udp_hdr, &info);
+				if (info.is_tunnel) {
+					tx_ol_flags |= PKT_TX_TUNNEL_GTP;
+					goto tunnel_update;
+				}
 				parse_vxlan_gpe(udp_hdr, &info);
 				if (info.is_tunnel) {
-					tx_ol_flags |= PKT_TX_TUNNEL_VXLAN_GPE;
-				} else {
-					parse_vxlan(udp_hdr, &info,
-						    m->packet_type);
-					if (info.is_tunnel)
-						tx_ol_flags |=
-							PKT_TX_TUNNEL_VXLAN;
+					tx_ol_flags |=
+						PKT_TX_TUNNEL_VXLAN_GPE;
+					goto tunnel_update;
 				}
+				parse_vxlan(udp_hdr, &info,
+					    m->packet_type);
+				if (info.is_tunnel)
+					tx_ol_flags |=
+						PKT_TX_TUNNEL_VXLAN;
 			} else if (info.l4_proto == IPPROTO_GRE) {
 				struct simple_gre_hdr *gre_hdr;
 
@@ -815,6 +891,7 @@ pkt_burst_checksum_forward(struct fwd_stream *fs)
 			}
 		}
 
+tunnel_update:
 		/* update l3_hdr and outer_l3_hdr if a tunnel was parsed */
 		if (info.is_tunnel) {
 			outer_l3_hdr = l3_hdr;
diff --git a/doc/api/doxy-api-index.md b/doc/api/doxy-api-index.md
index 6c2d888ee..8c21d426f 100644
--- a/doc/api/doxy-api-index.md
+++ b/doc/api/doxy-api-index.md
@@ -97,6 +97,7 @@ The public API headers are grouped by topics:
   [SCTP]               (@ref rte_sctp.h),
   [TCP]                (@ref rte_tcp.h),
   [UDP]                (@ref rte_udp.h),
+  [GTP]                (@ref rte_gtp.h),
   [GRO]                (@ref rte_gro.h),
   [GSO]                (@ref rte_gso.h),
   [frag/reass]         (@ref rte_ip_frag.h),
diff --git a/lib/librte_net/Makefile b/lib/librte_net/Makefile
index 1244c9fd5..4ad02aee0 100644
--- a/lib/librte_net/Makefile
+++ b/lib/librte_net/Makefile
@@ -20,7 +20,7 @@ SRCS-$(CONFIG_RTE_LIBRTE_NET) += rte_arp.c
 # install includes
 SYMLINK-$(CONFIG_RTE_LIBRTE_NET)-include := rte_ip.h rte_tcp.h rte_udp.h rte_esp.h
 SYMLINK-$(CONFIG_RTE_LIBRTE_NET)-include += rte_sctp.h rte_icmp.h rte_arp.h
-SYMLINK-$(CONFIG_RTE_LIBRTE_NET)-include += rte_ether.h rte_gre.h rte_net.h
+SYMLINK-$(CONFIG_RTE_LIBRTE_NET)-include += rte_ether.h rte_gre.h rte_gtp.h rte_net.h
 SYMLINK-$(CONFIG_RTE_LIBRTE_NET)-include += rte_net_crc.h rte_mpls.h
 
 include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/lib/librte_net/rte_gtp.h b/lib/librte_net/rte_gtp.h
new file mode 100644
index 000000000..febd99666
--- /dev/null
+++ b/lib/librte_net/rte_gtp.h
@@ -0,0 +1,52 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 1982, 1986, 1990, 1993
+ *      The Regents of the University of California.
+ * Copyright(c) 2010-2014 Intel Corporation.
+ * All rights reserved.
+ */
+
+#ifndef _RTE_GTP_H_
+#define _RTE_GTP_H_
+
+/**
+ * @file
+ *
+ * GTP-related defines
+ */
+
+#include <stdint.h>
+#include <rte_byteorder.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Simplified GTP protocol header.
+ * Contains 8-bit header info, 8-bit message type,
+ * 16-bit payload length after mandatory header, 32-bit TEID.
+ * No optional fields and next extension header.
+ */
+struct rte_gtp_hdr {
+	uint8_t gtp_hdr_info; /**< GTP header info */
+	uint8_t msg_type;     /**< GTP message type */
+	uint16_t plen;        /**< Total payload length */
+	uint32_t teid;        /**< Tunnel endpoint ID */
+} __attribute__((__packed__));
+
+/** GTP header length */
+#define RTE_ETHER_GTP_HLEN \
+	(sizeof(struct rte_udp_hdr) + sizeof(struct rte_gtp_hdr))
+/* GTP next protocal type */
+#define RTE_GTP_TYPE_IPV4 0x40 /**< GTP next protocal type IPv4 */
+#define RTE_GTP_TYPE_IPV6 0x60 /**< GTP next protocal type IPv6 */
+/* GTP destination port number */
+#define RTE_GTPC_UDP_PORT 2123 /**< GTP-C UDP destination port */
+#define RTE_GTPU_UDP_PORT 2152 /**< GTP-U UDP destination port */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* RTE_GTP_H_ */
+
-- 
2.17.1


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

* Re: [dpdk-dev] [PATCH v6] app/testpmd: enable GTP header parse and Tx checksum offload
  2019-10-22 15:45           ` Ferruh Yigit
@ 2019-10-23 17:23             ` Ferruh Yigit
  2019-10-25 22:43               ` Thomas Monjalon
  0 siblings, 1 reply; 20+ messages in thread
From: Ferruh Yigit @ 2019-10-23 17:23 UTC (permalink / raw)
  To: Ting Xu, dev; +Cc: wenzhuo.lu, jingjing.wu, bernard.iremonger, olivier.matz

On 10/22/2019 4:45 PM, Ferruh Yigit wrote:
> On 10/22/2019 5:26 PM, Ting Xu wrote:
>> This patch enables testpmd to forward GTP packet in csum fwd mode.
>> A GTP header structure (without optional fields and extension header)
>> is defined in new rte_gtp.h. A parser function in testpmd is added.
>> GTPU and GTPC packets are both supported, with respective UDP
>> destination port and GTP message type.
>>
>> Signed-off-by: Ting Xu <ting.xu@intel.com>
>>
>> ---
>> v6: complete doxygen documentation.
>> v5: create rte_gtp.h and move GTP header definition
>> to it.
>> v4: move GTP header definition to rte_ether.h
>> v3: correct coding style issue.
>> v2: modify commit log
>>
>> depend on patch: lib/mbuf: add GTP tunnel type flag.
> 
> Reviewed-by: Ferruh Yigit <ferruh.yigit@intel.com>
> 
> Will wait mbuf patch to be applied to get the patch.
> 

Applied to dpdk-next-net/master, thanks.

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

* Re: [dpdk-dev] [PATCH v6] app/testpmd: enable GTP header parse and Tx checksum offload
  2019-10-23 17:23             ` Ferruh Yigit
@ 2019-10-25 22:43               ` Thomas Monjalon
  2019-10-26 17:42                 ` Thomas Monjalon
  0 siblings, 1 reply; 20+ messages in thread
From: Thomas Monjalon @ 2019-10-25 22:43 UTC (permalink / raw)
  To: Ferruh Yigit
  Cc: dev, Ting Xu, wenzhuo.lu, jingjing.wu, bernard.iremonger, olivier.matz

23/10/2019 19:23, Ferruh Yigit:
> On 10/22/2019 4:45 PM, Ferruh Yigit wrote:
> > On 10/22/2019 5:26 PM, Ting Xu wrote:
> >> This patch enables testpmd to forward GTP packet in csum fwd mode.
> >> A GTP header structure (without optional fields and extension header)
> >> is defined in new rte_gtp.h. A parser function in testpmd is added.
> >> GTPU and GTPC packets are both supported, with respective UDP
> >> destination port and GTP message type.
> >>
> >> Signed-off-by: Ting Xu <ting.xu@intel.com>
> >>
> >> ---
> >> v6: complete doxygen documentation.
> >> v5: create rte_gtp.h and move GTP header definition
> >> to it.
> >> v4: move GTP header definition to rte_ether.h
> >> v3: correct coding style issue.
> >> v2: modify commit log
> >>
> >> depend on patch: lib/mbuf: add GTP tunnel type flag.
> > 
> > Reviewed-by: Ferruh Yigit <ferruh.yigit@intel.com>
> > 
> > Will wait mbuf patch to be applied to get the patch.
> > 
> 
> Applied to dpdk-next-net/master, thanks.

Sorry, dropped from pull in master.
An update of meson.build is missing and it makes me feel
something else may be missing.



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

* Re: [dpdk-dev] [PATCH v6] app/testpmd: enable GTP header parse and Tx checksum offload
  2019-10-22 16:26         ` [dpdk-dev] [PATCH v6] " Ting Xu
  2019-10-22 15:45           ` Ferruh Yigit
@ 2019-10-25 22:49           ` Thomas Monjalon
  2019-10-28  1:35             ` Xu, Ting
  1 sibling, 1 reply; 20+ messages in thread
From: Thomas Monjalon @ 2019-10-25 22:49 UTC (permalink / raw)
  To: Ting Xu
  Cc: dev, wenzhuo.lu, jingjing.wu, bernard.iremonger, olivier.matz,
	ferruh.yigit

22/10/2019 18:26, Ting Xu:
> This patch enables testpmd to forward GTP packet in csum fwd mode.
> A GTP header structure (without optional fields and extension header)
> is defined in new rte_gtp.h. A parser function in testpmd is added.
> GTPU and GTPC packets are both supported, with respective UDP
> destination port and GTP message type.
> 
> Signed-off-by: Ting Xu <ting.xu@intel.com>
> 
> ---
> v6: complete doxygen documentation.
> v5: create rte_gtp.h and move GTP header definition
> to it.
> v4: move GTP header definition to rte_ether.h
> v3: correct coding style issue.
> v2: modify commit log
> 
> depend on patch: lib/mbuf: add GTP tunnel type flag.
> ---
>  app/test-pmd/csumonly.c   | 97 +++++++++++++++++++++++++++++++++++----
>  doc/api/doxy-api-index.md |  1 +
>  lib/librte_net/Makefile   |  2 +-

You missed meson.build in addition of Makefile.

>  lib/librte_net/rte_gtp.h  | 52 +++++++++++++++++++++
>  4 files changed, 141 insertions(+), 11 deletions(-)
>  create mode 100644 lib/librte_net/rte_gtp.h

Does it deserve 2 separate patches? GTP header + testpmd use

[...]
> --- /dev/null
> +++ b/lib/librte_net/rte_gtp.h
[...]
> +
> +#endif /* RTE_GTP_H_ */
> +

Please remove this blank line at EOF. Such things are cleaned up sometimes:
	http://git.dpdk.org/dpdk/commit/?id=6f3f0acd95



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

* Re: [dpdk-dev] [PATCH v6] app/testpmd: enable GTP header parse and Tx checksum offload
  2019-10-25 22:43               ` Thomas Monjalon
@ 2019-10-26 17:42                 ` Thomas Monjalon
  0 siblings, 0 replies; 20+ messages in thread
From: Thomas Monjalon @ 2019-10-26 17:42 UTC (permalink / raw)
  To: Ting Xu
  Cc: dev, Ferruh Yigit, wenzhuo.lu, jingjing.wu, bernard.iremonger,
	olivier.matz

26/10/2019 00:43, Thomas Monjalon:
> 23/10/2019 19:23, Ferruh Yigit:
> > On 10/22/2019 4:45 PM, Ferruh Yigit wrote:
> > > On 10/22/2019 5:26 PM, Ting Xu wrote:
> > >> This patch enables testpmd to forward GTP packet in csum fwd mode.
> > >> A GTP header structure (without optional fields and extension header)
> > >> is defined in new rte_gtp.h. A parser function in testpmd is added.
> > >> GTPU and GTPC packets are both supported, with respective UDP
> > >> destination port and GTP message type.
> > >>
> > >> Signed-off-by: Ting Xu <ting.xu@intel.com>
> > >>
> > >> ---
> > >> v6: complete doxygen documentation.
> > >> v5: create rte_gtp.h and move GTP header definition
> > >> to it.
> > >> v4: move GTP header definition to rte_ether.h
> > >> v3: correct coding style issue.
> > >> v2: modify commit log
> > >>
> > >> depend on patch: lib/mbuf: add GTP tunnel type flag.
> > > 
> > > Reviewed-by: Ferruh Yigit <ferruh.yigit@intel.com>
> > > 
> > > Will wait mbuf patch to be applied to get the patch.
> > > 
> > 
> > Applied to dpdk-next-net/master, thanks.
> 
> Sorry, dropped from pull in master.
> An update of meson.build is missing and it makes me feel
> something else may be missing.

Changed my mind: I pull it in the master branch with few fixes.



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

* Re: [dpdk-dev] [PATCH v6] app/testpmd: enable GTP header parse and Tx checksum offload
  2019-10-25 22:49           ` Thomas Monjalon
@ 2019-10-28  1:35             ` Xu, Ting
  2019-10-28  8:38               ` Thomas Monjalon
  0 siblings, 1 reply; 20+ messages in thread
From: Xu, Ting @ 2019-10-28  1:35 UTC (permalink / raw)
  To: Thomas Monjalon
  Cc: dev, Lu, Wenzhuo, Wu,  Jingjing, Iremonger, Bernard,
	olivier.matz, Yigit, Ferruh

Hi, Thomas, 

Sorry for my mistake about missing meson.build. I have fixed it as well as others based on your comments.
However, I am not quite understand your last reply. Do I still need to send a new patch now or not?

Thanks for your patient help!

Best Regards,
Ting Xu

-----Original Message-----
From: Thomas Monjalon <thomas@monjalon.net> 
Sent: Saturday, October 26, 2019 6:49 AM
To: Xu, Ting <ting.xu@intel.com>
Cc: dev@dpdk.org; Lu, Wenzhuo <wenzhuo.lu@intel.com>; Wu, Jingjing <jingjing.wu@intel.com>; Iremonger, Bernard <bernard.iremonger@intel.com>; olivier.matz@6wind.com; Yigit, Ferruh <ferruh.yigit@intel.com>
Subject: Re: [dpdk-dev] [PATCH v6] app/testpmd: enable GTP header parse and Tx checksum offload

22/10/2019 18:26, Ting Xu:
> This patch enables testpmd to forward GTP packet in csum fwd mode.
> A GTP header structure (without optional fields and extension header) 
> is defined in new rte_gtp.h. A parser function in testpmd is added.
> GTPU and GTPC packets are both supported, with respective UDP 
> destination port and GTP message type.
> 
> Signed-off-by: Ting Xu <ting.xu@intel.com>
> 
> ---
> v6: complete doxygen documentation.
> v5: create rte_gtp.h and move GTP header definition to it.
> v4: move GTP header definition to rte_ether.h
> v3: correct coding style issue.
> v2: modify commit log
> 
> depend on patch: lib/mbuf: add GTP tunnel type flag.
> ---
>  app/test-pmd/csumonly.c   | 97 +++++++++++++++++++++++++++++++++++----
>  doc/api/doxy-api-index.md |  1 +
>  lib/librte_net/Makefile   |  2 +-

You missed meson.build in addition of Makefile.

>  lib/librte_net/rte_gtp.h  | 52 +++++++++++++++++++++
>  4 files changed, 141 insertions(+), 11 deletions(-)  create mode 
> 100644 lib/librte_net/rte_gtp.h

Does it deserve 2 separate patches? GTP header + testpmd use

[...]
> --- /dev/null
> +++ b/lib/librte_net/rte_gtp.h
[...]
> +
> +#endif /* RTE_GTP_H_ */
> +

Please remove this blank line at EOF. Such things are cleaned up sometimes:
	http://git.dpdk.org/dpdk/commit/?id=6f3f0acd95



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

* Re: [dpdk-dev] [PATCH v6] app/testpmd: enable GTP header parse and Tx checksum offload
  2019-10-28  1:35             ` Xu, Ting
@ 2019-10-28  8:38               ` Thomas Monjalon
  0 siblings, 0 replies; 20+ messages in thread
From: Thomas Monjalon @ 2019-10-28  8:38 UTC (permalink / raw)
  To: Xu, Ting
  Cc: dev, Lu, Wenzhuo, Wu, Jingjing, Iremonger, Bernard, olivier.matz,
	Yigit, Ferruh

28/10/2019 02:35, Xu, Ting:
> Hi, Thomas, 
> 
> Sorry for my mistake about missing meson.build. I have fixed it as well as others based on your comments.
> However, I am not quite understand your last reply. Do I still need to send a new patch now or not?

No, this is already merged: http://git.dpdk.org/dpdk/commit/?id=d8e5e69f3a


> Thanks for your patient help!
> 
> Best Regards,
> Ting Xu
> 
> -----Original Message-----
> From: Thomas Monjalon <thomas@monjalon.net> 
> Sent: Saturday, October 26, 2019 6:49 AM
> To: Xu, Ting <ting.xu@intel.com>
> Cc: dev@dpdk.org; Lu, Wenzhuo <wenzhuo.lu@intel.com>; Wu, Jingjing <jingjing.wu@intel.com>; Iremonger, Bernard <bernard.iremonger@intel.com>; olivier.matz@6wind.com; Yigit, Ferruh <ferruh.yigit@intel.com>
> Subject: Re: [dpdk-dev] [PATCH v6] app/testpmd: enable GTP header parse and Tx checksum offload
> 
> 22/10/2019 18:26, Ting Xu:
> > This patch enables testpmd to forward GTP packet in csum fwd mode.
> > A GTP header structure (without optional fields and extension header) 
> > is defined in new rte_gtp.h. A parser function in testpmd is added.
> > GTPU and GTPC packets are both supported, with respective UDP 
> > destination port and GTP message type.
> > 
> > Signed-off-by: Ting Xu <ting.xu@intel.com>
> > 
> > ---
> > v6: complete doxygen documentation.
> > v5: create rte_gtp.h and move GTP header definition to it.
> > v4: move GTP header definition to rte_ether.h
> > v3: correct coding style issue.
> > v2: modify commit log
> > 
> > depend on patch: lib/mbuf: add GTP tunnel type flag.
> > ---
> >  app/test-pmd/csumonly.c   | 97 +++++++++++++++++++++++++++++++++++----
> >  doc/api/doxy-api-index.md |  1 +
> >  lib/librte_net/Makefile   |  2 +-
> 
> You missed meson.build in addition of Makefile.
> 
> >  lib/librte_net/rte_gtp.h  | 52 +++++++++++++++++++++
> >  4 files changed, 141 insertions(+), 11 deletions(-)  create mode 
> > 100644 lib/librte_net/rte_gtp.h
> 
> Does it deserve 2 separate patches? GTP header + testpmd use
> 
> [...]
> > --- /dev/null
> > +++ b/lib/librte_net/rte_gtp.h
> [...]
> > +
> > +#endif /* RTE_GTP_H_ */
> > +
> 
> Please remove this blank line at EOF. Such things are cleaned up sometimes:
> 	http://git.dpdk.org/dpdk/commit/?id=6f3f0acd95




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

end of thread, other threads:[~2019-10-28  8:38 UTC | newest]

Thread overview: 20+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-10-17 15:26 [dpdk-dev] [PATCH v1] app/testpmd: enable GTP header parse and Tx checksum offload Ting Xu
2019-10-17 16:15 ` [dpdk-dev] [PATCH v2] " Ting Xu
2019-10-18 16:08   ` [dpdk-dev] [PATCH v3] " Ting Xu
2019-10-18 18:49     ` Ferruh Yigit
2019-10-21  2:28       ` Xu, Ting
2019-10-21 12:29     ` [dpdk-dev] [PATCH v4] " Ting Xu
2019-10-21  9:28       ` Ferruh Yigit
2019-10-21 10:52         ` Ferruh Yigit
2019-10-21 16:50           ` Olivier Matz
2019-10-22  5:34             ` Xu, Ting
2019-10-22 12:29       ` [dpdk-dev] [PATCH v5] " Ting Xu
2019-10-22  8:14         ` Ferruh Yigit
2019-10-22 16:26         ` [dpdk-dev] [PATCH v6] " Ting Xu
2019-10-22 15:45           ` Ferruh Yigit
2019-10-23 17:23             ` Ferruh Yigit
2019-10-25 22:43               ` Thomas Monjalon
2019-10-26 17:42                 ` Thomas Monjalon
2019-10-25 22:49           ` Thomas Monjalon
2019-10-28  1:35             ` Xu, Ting
2019-10-28  8:38               ` Thomas Monjalon

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