From: Jijiang Liu <jijiang.liu@intel.com>
To: dev@dpdk.org
Subject: [dpdk-dev] [PATCH 6/6] app/testpmd:test NVGRE Tx checksum offload
Date: Mon, 26 Jan 2015 11:43:25 +0800 [thread overview]
Message-ID: <1422243805-10906-7-git-send-email-jijiang.liu@intel.com> (raw)
In-Reply-To: <1422243805-10906-1-git-send-email-jijiang.liu@intel.com>
Enhance csum fwd engine and command lines based on current TX checksum framework in order to test TX Checksum offload for NVGRE packet.
It includes:
- IPv4 and IPv6 packet
- outer L3, inner L3 and L4 checksum offload for Tx side.
Note: The patch will need to be reworked after Olivier's patch set for enhancing checksum offload API is applied.
Signed-off-by: Jijiang Liu <jijiang.liu@intel.com>
---
app/test-pmd/cmdline.c | 19 +++++--
app/test-pmd/csumonly.c | 105 ++++++++++++++++++++++++++++----------
app/test-pmd/testpmd.h | 4 +-
lib/librte_pmd_i40e/i40e_rxtx.c | 2 +
4 files changed, 94 insertions(+), 36 deletions(-)
diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index ab25e24..54e0774 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -316,7 +316,7 @@ static void cmd_help_long_parsed(void *parsed_result,
" Disable hardware insertion of a VLAN header in"
" packets sent on a port.\n\n"
- "tx_cksum set (ip|udp|tcp|sctp|vxlan) (hw|sw) (port_id)\n"
+ "tx_cksum set (ip|udp|tcp|sctp|vxlan|nvgre) (hw|sw) (port_id)\n"
" Select hardware or software calculation of the"
" checksum with when transmitting a packet using the"
" csum forward engine.\n"
@@ -2899,8 +2899,9 @@ cmd_tx_cksum_parsed(void *parsed_result,
mask = TESTPMD_TX_OFFLOAD_TCP_CKSUM;
} else if (!strcmp(res->proto, "sctp")) {
mask = TESTPMD_TX_OFFLOAD_SCTP_CKSUM;
- } else if (!strcmp(res->proto, "vxlan")) {
- mask = TESTPMD_TX_OFFLOAD_VXLAN_CKSUM;
+ } else if (!strcmp(res->proto, "vxlan") ||
+ !strcmp(res->proto, "nvgre")) {
+ mask = TESTPMD_TX_OFFLOAD_TUNNEL_CKSUM;
}
if (hw)
@@ -2918,8 +2919,14 @@ cmd_tx_cksum_parsed(void *parsed_result,
(ol_flags & TESTPMD_TX_OFFLOAD_TCP_CKSUM) ? "hw" : "sw");
printf("SCTP checksum offload is %s\n",
(ol_flags & TESTPMD_TX_OFFLOAD_SCTP_CKSUM) ? "hw" : "sw");
- printf("VxLAN checksum offload is %s\n",
- (ol_flags & TESTPMD_TX_OFFLOAD_VXLAN_CKSUM) ? "hw" : "sw");
+
+ if (!strcmp(res->proto, "vxlan")) {
+ printf("VxLAN checksum offload is %s\n",
+ (ol_flags & TESTPMD_TX_OFFLOAD_TUNNEL_CKSUM) ? "hw" : "sw");
+ } else if (!strcmp(res->proto, "nvgre")) {
+ printf("NVGRE checksum offload is %s\n",
+ (ol_flags & TESTPMD_TX_OFFLOAD_TUNNEL_CKSUM) ? "hw" : "sw");
+ }
/* display warnings if configuration is not supported by the NIC */
rte_eth_dev_info_get(res->port_id, &dev_info);
@@ -2953,7 +2960,7 @@ cmdline_parse_token_string_t cmd_tx_cksum_mode =
mode, "set");
cmdline_parse_token_string_t cmd_tx_cksum_proto =
TOKEN_STRING_INITIALIZER(struct cmd_tx_cksum_result,
- proto, "ip#tcp#udp#sctp#vxlan");
+ proto, "ip#tcp#udp#sctp#vxlan#nvgre");
cmdline_parse_token_string_t cmd_tx_cksum_hwsw =
TOKEN_STRING_INITIALIZER(struct cmd_tx_cksum_result,
hwsw, "hw#sw");
diff --git a/app/test-pmd/csumonly.c b/app/test-pmd/csumonly.c
index 41711fd..8a87fbb 100644
--- a/app/test-pmd/csumonly.c
+++ b/app/test-pmd/csumonly.c
@@ -86,6 +86,12 @@
#define _htons(x) (x)
#endif
+/* simplified GRE header */
+struct simple_gre_hdr {
+ uint16_t flags;
+ uint16_t proto;
+};
+
static uint16_t
get_psd_sum(void *l3_hdr, uint16_t ethertype, uint64_t ol_flags)
{
@@ -244,42 +250,42 @@ process_inner_cksums(void *l3_hdr, uint16_t ethertype, uint16_t l3_len,
return ol_flags;
}
-/* Calculate the checksum of outer header (only vxlan is supported,
- * meaning IP + UDP). The caller already checked that it's a vxlan
+/* Calculate the checksum of outer header (only vxlan/nvgre is supported,
+ * meaning IP + UDP/GRE). The caller already checked that it's a vxlan/NVGRE
* packet */
static uint64_t
process_outer_cksums(void *outer_l3_hdr, uint16_t outer_ethertype,
- uint16_t outer_l3_len, uint16_t testpmd_ol_flags)
+ uint16_t outer_l3_len, uint16_t testpmd_ol_flags, uint16_t l4_prot)
{
struct ipv4_hdr *ipv4_hdr = outer_l3_hdr;
struct ipv6_hdr *ipv6_hdr = outer_l3_hdr;
struct udp_hdr *udp_hdr;
uint64_t ol_flags = 0;
- if (testpmd_ol_flags & TESTPMD_TX_OFFLOAD_VXLAN_CKSUM)
- ol_flags |= PKT_TX_UDP_TUNNEL_PKT;
-
if (outer_ethertype == _htons(ETHER_TYPE_IPv4)) {
ipv4_hdr->hdr_checksum = 0;
- if (testpmd_ol_flags & TESTPMD_TX_OFFLOAD_VXLAN_CKSUM)
+ if (testpmd_ol_flags & TESTPMD_TX_OFFLOAD_TUNNEL_CKSUM)
ol_flags |= PKT_TX_OUTER_IP_CKSUM;
else
ipv4_hdr->hdr_checksum = rte_ipv4_cksum(ipv4_hdr);
- } else if (testpmd_ol_flags & TESTPMD_TX_OFFLOAD_VXLAN_CKSUM)
+ } else if (testpmd_ol_flags & TESTPMD_TX_OFFLOAD_TUNNEL_CKSUM)
ol_flags |= PKT_TX_OUTER_IPV6;
- udp_hdr = (struct udp_hdr *)((char *)outer_l3_hdr + outer_l3_len);
- /* do not recalculate udp cksum if it was 0 */
- if (udp_hdr->dgram_cksum != 0) {
- udp_hdr->dgram_cksum = 0;
- if (outer_ethertype == _htons(ETHER_TYPE_IPv4))
- udp_hdr->dgram_cksum =
- rte_ipv4_udptcp_cksum(ipv4_hdr, udp_hdr);
- else
- udp_hdr->dgram_cksum =
- rte_ipv6_udptcp_cksum(ipv6_hdr, udp_hdr);
- }
+ if (l4_prot == IPPROTO_UDP) {
+ udp_hdr = (struct udp_hdr *)((char *)outer_l3_hdr
+ + outer_l3_len);
+ /* do not recalculate udp cksum if it was 0 */
+ if (udp_hdr->dgram_cksum != 0) {
+ udp_hdr->dgram_cksum = 0;
+ if (outer_ethertype == _htons(ETHER_TYPE_IPv4))
+ udp_hdr->dgram_cksum =
+ rte_ipv4_udptcp_cksum(ipv4_hdr, udp_hdr);
+ else
+ udp_hdr->dgram_cksum =
+ rte_ipv6_udptcp_cksum(ipv6_hdr, udp_hdr);
+ }
+ } /* else if (l4_proto == IPPROTO_GRE), nothing to do here*/
return ol_flags;
}
@@ -299,12 +305,15 @@ process_outer_cksums(void *outer_l3_hdr, uint16_t outer_ethertype,
* Ether / (vlan) / IP|IP6 / UDP|TCP|SCTP .
* Ether / (vlan) / outer IP|IP6 / outer UDP / VxLAN / Ether / IP|IP6 /
* UDP|TCP|SCTP
+ * Ether / (vlan) / outer IP|IP6 / GRE / Ether / IP|IP6 /
+ * UDP|TCP|SCTP
*
* The testpmd command line for this forward engine sets the flags
* TESTPMD_TX_OFFLOAD_* in ports[tx_port].tx_ol_flags. They control
* wether a checksum must be calculated in software or in hardware. The
* IP, UDP, TCP and SCTP flags always concern the inner layer. The
- * VxLAN flag concerns the outer IP (if packet is recognized as a vxlan packet).
+ * TUNNEL flag concerns the outer IP (if packet is recognized as a vxlan/nvgre
+ * packet).
*/
static void
pkt_burst_checksum_forward(struct fwd_stream *fs)
@@ -315,6 +324,7 @@ pkt_burst_checksum_forward(struct fwd_stream *fs)
struct ether_hdr *eth_hdr;
void *l3_hdr = NULL, *outer_l3_hdr = NULL; /* can be IPv4 or IPv6 */
struct udp_hdr *udp_hdr;
+ struct simple_gre_hdr *gre_hdr;
uint16_t nb_rx;
uint16_t nb_tx;
uint16_t i;
@@ -386,17 +396,20 @@ pkt_burst_checksum_forward(struct fwd_stream *fs)
tunnel = 1;
/* currently, this flag is set by i40e only if the
- * packet is vxlan */
+ * packet is tunneled packet */
} else if (m->ol_flags & (PKT_RX_TUNNEL_IPV4_HDR |
PKT_RX_TUNNEL_IPV6_HDR))
tunnel = 1;
if (tunnel == 1) {
+ if (testpmd_ol_flags &
+ TESTPMD_TX_OFFLOAD_TUNNEL_CKSUM)
+ ol_flags |= PKT_TX_UDP_TUNNEL_PKT;
+
outer_ethertype = ethertype;
outer_l2_len = l2_len;
outer_l3_len = l3_len;
outer_l3_hdr = l3_hdr;
-
eth_hdr = (struct ether_hdr *)((char *)udp_hdr +
sizeof(struct udp_hdr) +
sizeof(struct vxlan_hdr));
@@ -407,6 +420,35 @@ pkt_burst_checksum_forward(struct fwd_stream *fs)
}
}
+ if ((l4_proto == IPPROTO_GRE)
+ && ((m->ol_flags & (PKT_RX_TUNNEL_IPV4_HDR |
+ PKT_RX_TUNNEL_IPV6_HDR)))) {
+ gre_hdr = (struct simple_gre_hdr *)((char *)l3_hdr + l3_len);
+ if (gre_hdr->proto == _htons(ETHER_TYPE_TEB)) {
+ l4_tun_len = sizeof(struct nvgre_hdr);
+ tunnel = 1;
+ }
+
+ if (tunnel == 1) {
+ if (testpmd_ol_flags &
+ TESTPMD_TX_OFFLOAD_TUNNEL_CKSUM)
+ ol_flags |= PKT_TX_GRE_TUNNEL_PKT;
+
+ outer_ethertype = ethertype;
+ outer_l2_len = l2_len;
+ outer_l3_len = l3_len;
+ outer_l3_hdr = l3_hdr;
+
+ /* currently, only NVGRE packet is supported */
+ eth_hdr = (struct ether_hdr *)((char *)gre_hdr +
+ sizeof(struct nvgre_hdr));
+ parse_ethernet(eth_hdr, ðertype, &l2_len,
+ &l3_len, &l4_proto, &l4_len);
+ l3_hdr = (char *)eth_hdr + l2_len;
+ }
+
+ }
+
/* step 2: change all source IPs (v4 or v6) so we need
* to recompute the chksums even if they were correct */
@@ -428,13 +470,14 @@ pkt_burst_checksum_forward(struct fwd_stream *fs)
* processed in hardware. */
if (tunnel == 1) {
ol_flags |= process_outer_cksums(outer_l3_hdr,
- outer_ethertype, outer_l3_len, testpmd_ol_flags);
+ outer_ethertype, outer_l3_len, testpmd_ol_flags,
+ l4_proto);
}
/* step 4: fill the mbuf meta data (flags and header lengths) */
if (tunnel == 1) {
- if (testpmd_ol_flags & TESTPMD_TX_OFFLOAD_VXLAN_CKSUM) {
+ if (testpmd_ol_flags & TESTPMD_TX_OFFLOAD_TUNNEL_CKSUM) {
m->outer_l2_len = outer_l2_len;
m->outer_l3_len = outer_l3_len;
m->l2_len = l4_tun_len + l2_len;
@@ -446,9 +489,15 @@ pkt_burst_checksum_forward(struct fwd_stream *fs)
we changed the ip, but it shows that
we can process the inner header cksum
in the nic */
- m->l2_len = outer_l2_len + outer_l3_len +
- sizeof(struct udp_hdr) +
- sizeof(struct vxlan_hdr) + l2_len;
+ if (l4_proto == IPPROTO_UDP)
+ m->l2_len = outer_l2_len + outer_l3_len +
+ sizeof(struct udp_hdr) +
+ sizeof(struct vxlan_hdr) + l2_len;
+
+ /* currently, only NVGRE is supported */
+ else if (l4_proto == IPPROTO_GRE)
+ m->l2_len = outer_l2_len + outer_l3_len +
+ sizeof(struct nvgre_hdr) + l2_len;
m->l3_len = l3_len;
m->l4_len = l4_len;
}
@@ -505,7 +554,7 @@ pkt_burst_checksum_forward(struct fwd_stream *fs)
"m->l4_len=%d\n",
m->l2_len, m->l3_len, m->l4_len);
if ((tunnel == 1) &&
- (testpmd_ol_flags & TESTPMD_TX_OFFLOAD_VXLAN_CKSUM))
+ (testpmd_ol_flags & TESTPMD_TX_OFFLOAD_TUNNEL_CKSUM))
printf("tx: m->outer_l2_len=%d m->outer_l3_len=%d\n",
m->outer_l2_len, m->outer_l3_len);
if (tso_segsz != 0)
diff --git a/app/test-pmd/testpmd.h b/app/test-pmd/testpmd.h
index f8b0740..528457b 100644
--- a/app/test-pmd/testpmd.h
+++ b/app/test-pmd/testpmd.h
@@ -125,8 +125,8 @@ struct fwd_stream {
#define TESTPMD_TX_OFFLOAD_TCP_CKSUM 0x0004
/** Offload SCTP checksum in csum forward engine */
#define TESTPMD_TX_OFFLOAD_SCTP_CKSUM 0x0008
-/** Offload VxLAN checksum in csum forward engine */
-#define TESTPMD_TX_OFFLOAD_VXLAN_CKSUM 0x0010
+/** Offload tunneled packet checksum in csum forward engine */
+#define TESTPMD_TX_OFFLOAD_TUNNEL_CKSUM 0x0010
/** Insert VLAN header in forward engine */
#define TESTPMD_TX_OFFLOAD_INSERT_VLAN 0x0020
diff --git a/lib/librte_pmd_i40e/i40e_rxtx.c b/lib/librte_pmd_i40e/i40e_rxtx.c
index 6c1e324..bf6c17c 100644
--- a/lib/librte_pmd_i40e/i40e_rxtx.c
+++ b/lib/librte_pmd_i40e/i40e_rxtx.c
@@ -1169,6 +1169,8 @@ i40e_calc_context_desc(uint64_t flags)
if (flags | PKT_TX_UDP_TUNNEL_PKT)
mask |= PKT_TX_UDP_TUNNEL_PKT;
+ if (flags | PKT_TX_GRE_TUNNEL_PKT)
+ mask |= PKT_TX_GRE_TUNNEL_PKT;
#ifdef RTE_LIBRTE_IEEE1588
mask |= PKT_TX_IEEE1588_TMST;
--
1.7.7.6
next prev parent reply other threads:[~2015-01-26 3:43 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-01-26 3:43 [dpdk-dev] [PATCH 0/6] Support NVGRE on i40e Jijiang Liu
2015-01-26 3:43 ` [dpdk-dev] [PATCH 1/6] librte_ether:add NVGRE header Jijiang Liu
2015-01-26 3:43 ` [dpdk-dev] [PATCH 2/6] i40e:support RX tunnel filter for NVGRE packet Jijiang Liu
2015-01-26 3:43 ` [dpdk-dev] [PATCH 3/6] app/testpmd:test " Jijiang Liu
2015-01-26 3:43 ` [dpdk-dev] [PATCH 4/6] mbuf:add a GRE TX tunnel ol_flag Jijiang Liu
2015-01-26 3:43 ` [dpdk-dev] [PATCH 5/6] i40e:support GRE tunnel TX checksum offload Jijiang Liu
2015-01-26 3:43 ` Jijiang Liu [this message]
2015-01-27 5:46 ` [dpdk-dev] [PATCH 0/6] Support NVGRE on i40e Cao, Min
2015-01-28 11:08 ` Olivier MATZ
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1422243805-10906-7-git-send-email-jijiang.liu@intel.com \
--to=jijiang.liu@intel.com \
--cc=dev@dpdk.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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).