DPDK patches and discussions
 help / color / mirror / Atom feed
From: Helin Zhang <helin.zhang@intel.com>
To: dev@dpdk.org
Subject: [dpdk-dev] [PATCH v2 5/6] app/testpmd: add test cases for qinq stripping and insertion
Date: Tue,  2 Jun 2015 11:16:06 +0800	[thread overview]
Message-ID: <1433214967-22247-6-git-send-email-helin.zhang@intel.com> (raw)
In-Reply-To: <1433214967-22247-1-git-send-email-helin.zhang@intel.com>

If double vlan is detected, its stripped flag and vlan tags can be
printed on rxonly mode. Test command of 'tx_vlan set' is expanded
to set both single and double vlan tags on TX side for each packets
to be sent out.

Signed-off-by: Helin Zhang <helin.zhang@intel.com>
---
 app/test-pmd/cmdline.c | 78 +++++++++++++++++++++++++++++++++++++++++++++-----
 app/test-pmd/config.c  | 21 +++++++++++++-
 app/test-pmd/flowgen.c |  4 ++-
 app/test-pmd/macfwd.c  |  3 ++
 app/test-pmd/macswap.c |  3 ++
 app/test-pmd/rxonly.c  |  3 ++
 app/test-pmd/testpmd.h |  6 +++-
 app/test-pmd/txonly.c  |  8 ++++--
 8 files changed, 114 insertions(+), 12 deletions(-)

diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index f01db2a..db2e73e 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -304,9 +304,9 @@ static void cmd_help_long_parsed(void *parsed_result,
 			"rx_vxlan_port rm (udp_port) (port_id)\n"
 			"    Remove an UDP port for VXLAN packet filter on a port\n\n"
 
-			"tx_vlan set vlan_id (port_id)\n"
-			"    Set hardware insertion of VLAN ID in packets sent"
-			" on a port.\n\n"
+			"tx_vlan set (port_id) vlan_id[, vlan_id_outer]\n"
+			"    Set hardware insertion of VLAN IDs (single or double VLAN "
+			"depends on the number of VLAN IDs) in packets sent on a port.\n\n"
 
 			"tx_vlan set pvid port_id vlan_id (on|off)\n"
 			"    Set port based TX VLAN insertion.\n\n"
@@ -2799,8 +2799,8 @@ cmdline_parse_inst_t cmd_rx_vlan_filter = {
 struct cmd_tx_vlan_set_result {
 	cmdline_fixed_string_t tx_vlan;
 	cmdline_fixed_string_t set;
-	uint16_t vlan_id;
 	uint8_t port_id;
+	uint16_t vlan_id;
 };
 
 static void
@@ -2809,6 +2809,13 @@ cmd_tx_vlan_set_parsed(void *parsed_result,
 		       __attribute__((unused)) void *data)
 {
 	struct cmd_tx_vlan_set_result *res = parsed_result;
+	int vlan_offload = rte_eth_dev_get_vlan_offload(res->port_id);
+
+	if (vlan_offload & ETH_VLAN_EXTEND_OFFLOAD) {
+		printf("Error, as QinQ has been enabled.\n");
+		return;
+	}
+
 	tx_vlan_set(res->port_id, res->vlan_id);
 }
 
@@ -2828,13 +2835,69 @@ cmdline_parse_token_num_t cmd_tx_vlan_set_portid =
 cmdline_parse_inst_t cmd_tx_vlan_set = {
 	.f = cmd_tx_vlan_set_parsed,
 	.data = NULL,
-	.help_str = "enable hardware insertion of a VLAN header with a given "
-	"TAG Identifier in packets sent on a port",
+	.help_str = "enable hardware insertion of a single VLAN header "
+		"with a given TAG Identifier in packets sent on a port",
 	.tokens = {
 		(void *)&cmd_tx_vlan_set_tx_vlan,
 		(void *)&cmd_tx_vlan_set_set,
-		(void *)&cmd_tx_vlan_set_vlanid,
 		(void *)&cmd_tx_vlan_set_portid,
+		(void *)&cmd_tx_vlan_set_vlanid,
+		NULL,
+	},
+};
+
+/* *** ENABLE HARDWARE INSERTION OF Double VLAN HEADER IN TX PACKETS *** */
+struct cmd_tx_vlan_set_qinq_result {
+	cmdline_fixed_string_t tx_vlan;
+	cmdline_fixed_string_t set;
+	uint8_t port_id;
+	uint16_t vlan_id;
+	uint16_t vlan_id_outer;
+};
+
+static void
+cmd_tx_vlan_set_qinq_parsed(void *parsed_result,
+			    __attribute__((unused)) struct cmdline *cl,
+			    __attribute__((unused)) void *data)
+{
+	struct cmd_tx_vlan_set_qinq_result *res = parsed_result;
+	int vlan_offload = rte_eth_dev_get_vlan_offload(res->port_id);
+
+	if (!(vlan_offload & ETH_VLAN_EXTEND_OFFLOAD)) {
+		printf("Error, as QinQ hasn't been enabled.\n");
+		return;
+	}
+
+	tx_qinq_set(res->port_id, res->vlan_id, res->vlan_id_outer);
+}
+
+cmdline_parse_token_string_t cmd_tx_vlan_set_qinq_tx_vlan =
+	TOKEN_STRING_INITIALIZER(struct cmd_tx_vlan_set_qinq_result,
+		tx_vlan, "tx_vlan");
+cmdline_parse_token_string_t cmd_tx_vlan_set_qinq_set =
+	TOKEN_STRING_INITIALIZER(struct cmd_tx_vlan_set_qinq_result,
+		set, "set");
+cmdline_parse_token_num_t cmd_tx_vlan_set_qinq_portid =
+	TOKEN_NUM_INITIALIZER(struct cmd_tx_vlan_set_qinq_result,
+		port_id, UINT8);
+cmdline_parse_token_num_t cmd_tx_vlan_set_qinq_vlanid =
+	TOKEN_NUM_INITIALIZER(struct cmd_tx_vlan_set_qinq_result,
+		vlan_id, UINT16);
+cmdline_parse_token_num_t cmd_tx_vlan_set_qinq_vlanid_outer =
+	TOKEN_NUM_INITIALIZER(struct cmd_tx_vlan_set_qinq_result,
+		vlan_id_outer, UINT16);
+
+cmdline_parse_inst_t cmd_tx_vlan_set_qinq = {
+	.f = cmd_tx_vlan_set_qinq_parsed,
+	.data = NULL,
+	.help_str = "enable hardware insertion of double VLAN header "
+		"with given TAG Identifiers in packets sent on a port",
+	.tokens = {
+		(void *)&cmd_tx_vlan_set_qinq_tx_vlan,
+		(void *)&cmd_tx_vlan_set_qinq_set,
+		(void *)&cmd_tx_vlan_set_qinq_portid,
+		(void *)&cmd_tx_vlan_set_qinq_vlanid,
+		(void *)&cmd_tx_vlan_set_qinq_vlanid_outer,
 		NULL,
 	},
 };
@@ -8782,6 +8845,7 @@ cmdline_parse_ctx_t main_ctx[] = {
 	(cmdline_parse_inst_t *)&cmd_rx_vlan_filter_all,
 	(cmdline_parse_inst_t *)&cmd_rx_vlan_filter,
 	(cmdline_parse_inst_t *)&cmd_tx_vlan_set,
+	(cmdline_parse_inst_t *)&cmd_tx_vlan_set_qinq,
 	(cmdline_parse_inst_t *)&cmd_tx_vlan_reset,
 	(cmdline_parse_inst_t *)&cmd_tx_vlan_set_pvid,
 	(cmdline_parse_inst_t *)&cmd_csum_set,
diff --git a/app/test-pmd/config.c b/app/test-pmd/config.c
index f788ed5..8c49e4d 100644
--- a/app/test-pmd/config.c
+++ b/app/test-pmd/config.c
@@ -1732,16 +1732,35 @@ tx_vlan_set(portid_t port_id, uint16_t vlan_id)
 		return;
 	if (vlan_id_is_invalid(vlan_id))
 		return;
+	tx_vlan_reset(port_id);
 	ports[port_id].tx_ol_flags |= TESTPMD_TX_OFFLOAD_INSERT_VLAN;
 	ports[port_id].tx_vlan_id = vlan_id;
 }
 
 void
+tx_qinq_set(portid_t port_id, uint16_t vlan_id, uint16_t vlan_id_outer)
+{
+	if (port_id_is_invalid(port_id, ENABLED_WARN))
+		return;
+	if (vlan_id_is_invalid(vlan_id))
+		return;
+	if (vlan_id_is_invalid(vlan_id_outer))
+		return;
+	tx_vlan_reset(port_id);
+	ports[port_id].tx_ol_flags |= TESTPMD_TX_OFFLOAD_INSERT_QINQ;
+	ports[port_id].tx_vlan_id = vlan_id;
+	ports[port_id].tx_vlan_id_outer = vlan_id_outer;
+}
+
+void
 tx_vlan_reset(portid_t port_id)
 {
 	if (port_id_is_invalid(port_id, ENABLED_WARN))
 		return;
-	ports[port_id].tx_ol_flags &= ~TESTPMD_TX_OFFLOAD_INSERT_VLAN;
+	ports[port_id].tx_ol_flags &= ~(TESTPMD_TX_OFFLOAD_INSERT_VLAN |
+				TESTPMD_TX_OFFLOAD_INSERT_QINQ);
+	ports[port_id].tx_vlan_id = 0;
+	ports[port_id].tx_vlan_id_outer = 0;
 }
 
 void
diff --git a/app/test-pmd/flowgen.c b/app/test-pmd/flowgen.c
index 72016c9..fce96dc 100644
--- a/app/test-pmd/flowgen.c
+++ b/app/test-pmd/flowgen.c
@@ -136,7 +136,7 @@ pkt_burst_flow_gen(struct fwd_stream *fs)
 	struct ether_hdr *eth_hdr;
 	struct ipv4_hdr *ip_hdr;
 	struct udp_hdr *udp_hdr;
-	uint16_t vlan_tci;
+	uint16_t vlan_tci, vlan_tci_outer;
 	uint16_t ol_flags;
 	uint16_t nb_rx;
 	uint16_t nb_tx;
@@ -163,6 +163,7 @@ pkt_burst_flow_gen(struct fwd_stream *fs)
 
 	mbp = current_fwd_lcore()->mbp;
 	vlan_tci = ports[fs->tx_port].tx_vlan_id;
+	vlan_tci_outer = ports[fs->tx_port].tx_vlan_id_outer;
 	ol_flags = ports[fs->tx_port].tx_ol_flags;
 
 	for (nb_pkt = 0; nb_pkt < nb_pkt_per_burst; nb_pkt++) {
@@ -208,6 +209,7 @@ pkt_burst_flow_gen(struct fwd_stream *fs)
 		pkt->pkt_len		= pkt_size;
 		pkt->ol_flags		= ol_flags;
 		pkt->vlan_tci		= vlan_tci;
+		pkt->vlan_tci_outer	= vlan_tci_outer;
 		pkt->l2_len		= sizeof(struct ether_hdr);
 		pkt->l3_len		= sizeof(struct ipv4_hdr);
 		pkts_burst[nb_pkt]	= pkt;
diff --git a/app/test-pmd/macfwd.c b/app/test-pmd/macfwd.c
index 035e5eb..3b7fffb 100644
--- a/app/test-pmd/macfwd.c
+++ b/app/test-pmd/macfwd.c
@@ -110,6 +110,8 @@ pkt_burst_mac_forward(struct fwd_stream *fs)
 	txp = &ports[fs->tx_port];
 	if (txp->tx_ol_flags & TESTPMD_TX_OFFLOAD_INSERT_VLAN)
 		ol_flags = PKT_TX_VLAN_PKT;
+	if (txp->tx_ol_flags & TESTPMD_TX_OFFLOAD_INSERT_QINQ)
+		ol_flags |= PKT_TX_QINQ_PKT;
 	for (i = 0; i < nb_rx; i++) {
 		mb = pkts_burst[i];
 		eth_hdr = rte_pktmbuf_mtod(mb, struct ether_hdr *);
@@ -121,6 +123,7 @@ pkt_burst_mac_forward(struct fwd_stream *fs)
 		mb->l2_len = sizeof(struct ether_hdr);
 		mb->l3_len = sizeof(struct ipv4_hdr);
 		mb->vlan_tci = txp->tx_vlan_id;
+		mb->vlan_tci_outer = txp->tx_vlan_id_outer;
 	}
 	nb_tx = rte_eth_tx_burst(fs->tx_port, fs->tx_queue, pkts_burst, nb_rx);
 	fs->tx_packets += nb_tx;
diff --git a/app/test-pmd/macswap.c b/app/test-pmd/macswap.c
index 6729849..154889d 100644
--- a/app/test-pmd/macswap.c
+++ b/app/test-pmd/macswap.c
@@ -110,6 +110,8 @@ pkt_burst_mac_swap(struct fwd_stream *fs)
 	txp = &ports[fs->tx_port];
 	if (txp->tx_ol_flags & TESTPMD_TX_OFFLOAD_INSERT_VLAN)
 		ol_flags = PKT_TX_VLAN_PKT;
+	if (txp->tx_ol_flags & TESTPMD_TX_OFFLOAD_INSERT_QINQ)
+		ol_flags |= PKT_TX_QINQ_PKT;
 	for (i = 0; i < nb_rx; i++) {
 		mb = pkts_burst[i];
 		eth_hdr = rte_pktmbuf_mtod(mb, struct ether_hdr *);
@@ -123,6 +125,7 @@ pkt_burst_mac_swap(struct fwd_stream *fs)
 		mb->l2_len = sizeof(struct ether_hdr);
 		mb->l3_len = sizeof(struct ipv4_hdr);
 		mb->vlan_tci = txp->tx_vlan_id;
+		mb->vlan_tci_outer = txp->tx_vlan_id_outer;
 	}
 	nb_tx = rte_eth_tx_burst(fs->tx_port, fs->tx_queue, pkts_burst, nb_rx);
 	fs->tx_packets += nb_tx;
diff --git a/app/test-pmd/rxonly.c b/app/test-pmd/rxonly.c
index ac56090..f6a2f84 100644
--- a/app/test-pmd/rxonly.c
+++ b/app/test-pmd/rxonly.c
@@ -160,6 +160,9 @@ pkt_burst_receive(struct fwd_stream *fs)
 		}
 		if (ol_flags & PKT_RX_VLAN_PKT)
 			printf(" - VLAN tci=0x%x", mb->vlan_tci);
+		if (ol_flags & PKT_RX_QINQ_PKT)
+			printf(" - QinQ VLAN tci=0x%x, VLAN tci outer=0x%x",
+					mb->vlan_tci, mb->vlan_tci_outer);
 		if (is_encapsulation) {
 			struct ipv4_hdr *ipv4_hdr;
 			struct ipv6_hdr *ipv6_hdr;
diff --git a/app/test-pmd/testpmd.h b/app/test-pmd/testpmd.h
index c3b6700..e71951b 100644
--- a/app/test-pmd/testpmd.h
+++ b/app/test-pmd/testpmd.h
@@ -133,6 +133,8 @@ struct fwd_stream {
 #define TESTPMD_TX_OFFLOAD_PARSE_TUNNEL      0x0020
 /** Insert VLAN header in forward engine */
 #define TESTPMD_TX_OFFLOAD_INSERT_VLAN       0x0040
+/** Insert double VLAN header in forward engine */
+#define TESTPMD_TX_OFFLOAD_INSERT_QINQ       0x0080
 
 /**
  * The data structure associated with each port.
@@ -149,7 +151,8 @@ struct rte_port {
 	unsigned int            socket_id;  /**< For NUMA support */
 	uint16_t                tx_ol_flags;/**< TX Offload Flags (TESTPMD_TX_OFFLOAD...). */
 	uint16_t                tso_segsz;  /**< MSS for segmentation offload. */
-	uint16_t                tx_vlan_id; /**< Tag Id. in TX VLAN packets. */
+	uint16_t                tx_vlan_id;/**< The tag ID */
+	uint16_t                tx_vlan_id_outer;/**< The outer tag ID */
 	void                    *fwd_ctx;   /**< Forwarding mode context */
 	uint64_t                rx_bad_ip_csum; /**< rx pkts with bad ip checksum  */
 	uint64_t                rx_bad_l4_csum; /**< rx pkts with bad l4 checksum */
@@ -513,6 +516,7 @@ int rx_vft_set(portid_t port_id, uint16_t vlan_id, int on);
 void vlan_extend_set(portid_t port_id, int on);
 void vlan_tpid_set(portid_t port_id, uint16_t tp_id);
 void tx_vlan_set(portid_t port_id, uint16_t vlan_id);
+void tx_qinq_set(portid_t port_id, uint16_t vlan_id, uint16_t vlan_id_outer);
 void tx_vlan_reset(portid_t port_id);
 void tx_vlan_pvid_set(portid_t port_id, uint16_t vlan_id, int on);
 
diff --git a/app/test-pmd/txonly.c b/app/test-pmd/txonly.c
index ca32c85..8ce6109 100644
--- a/app/test-pmd/txonly.c
+++ b/app/test-pmd/txonly.c
@@ -202,7 +202,7 @@ pkt_burst_transmit(struct fwd_stream *fs)
 	struct ether_hdr eth_hdr;
 	uint16_t nb_tx;
 	uint16_t nb_pkt;
-	uint16_t vlan_tci;
+	uint16_t vlan_tci, vlan_tci_outer;
 	uint64_t ol_flags = 0;
 	uint8_t  i;
 #ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES
@@ -218,8 +218,11 @@ pkt_burst_transmit(struct fwd_stream *fs)
 	mbp = current_fwd_lcore()->mbp;
 	txp = &ports[fs->tx_port];
 	vlan_tci = txp->tx_vlan_id;
+	vlan_tci_outer = txp->tx_vlan_id_outer;
 	if (txp->tx_ol_flags & TESTPMD_TX_OFFLOAD_INSERT_VLAN)
 		ol_flags = PKT_TX_VLAN_PKT;
+	if (txp->tx_ol_flags & TESTPMD_TX_OFFLOAD_INSERT_QINQ)
+		ol_flags |= PKT_TX_QINQ_PKT;
 	for (nb_pkt = 0; nb_pkt < nb_pkt_per_burst; nb_pkt++) {
 		pkt = tx_mbuf_alloc(mbp);
 		if (pkt == NULL) {
@@ -266,7 +269,8 @@ pkt_burst_transmit(struct fwd_stream *fs)
 		pkt->nb_segs = tx_pkt_nb_segs;
 		pkt->pkt_len = tx_pkt_length;
 		pkt->ol_flags = ol_flags;
-		pkt->vlan_tci  = vlan_tci;
+		pkt->vlan_tci = vlan_tci;
+		pkt->vlan_tci_outer = vlan_tci_outer;
 		pkt->l2_len = sizeof(struct ether_hdr);
 		pkt->l3_len = sizeof(struct ipv4_hdr);
 		pkts_burst[nb_pkt] = pkt;
-- 
1.9.3

  parent reply	other threads:[~2015-06-02  3:16 UTC|newest]

Thread overview: 55+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-05-05  2:32 [dpdk-dev] [PATCH RFC 0/6] support of QinQ stripping and insertion of i40e Helin Zhang
2015-05-05  2:32 ` [dpdk-dev] [PATCH RFC 1/6] mbuf: update mbuf structure for QinQ support Helin Zhang
2015-05-05 11:04   ` Ananyev, Konstantin
2015-05-05 15:42     ` Chilikin, Andrey
2015-05-05 22:37       ` Ananyev, Konstantin
2015-05-06  4:07         ` Zhang, Helin
2015-05-06  4:06     ` Zhang, Helin
2015-05-06  8:39       ` Bruce Richardson
2015-05-06  8:48         ` Zhang, Helin
2015-05-05  2:32 ` [dpdk-dev] [PATCH RFC 2/6] i40e: reconfigure the hardware to support QinQ stripping/insertion Helin Zhang
2015-05-05  2:32 ` [dpdk-dev] [PATCH RFC 3/6] i40e: support of QinQ stripping/insertion in RX/TX Helin Zhang
2015-05-05  2:32 ` [dpdk-dev] [PATCH RFC 4/6] ethdev: add QinQ offload capability flags Helin Zhang
2015-05-05  2:32 ` [dpdk-dev] [PATCH RFC 5/6] i40e: update of " Helin Zhang
2015-05-05  2:32 ` [dpdk-dev] [PATCH RFC 6/6] app/testpmd: support of QinQ stripping and insertion Helin Zhang
2015-05-26  8:36 ` [dpdk-dev] [PATCH 0/5] support i40e " Helin Zhang
2015-05-26  8:36   ` [dpdk-dev] [PATCH 1/5] ixgbe: remove a discarded source line Helin Zhang
2015-06-01  8:50     ` Olivier MATZ
2015-06-02  1:45       ` Zhang, Helin
2015-05-26  8:36   ` [dpdk-dev] [PATCH 2/5] mbuf: use the reserved 16 bits for double vlan Helin Zhang
2015-05-26 14:55     ` Stephen Hemminger
2015-05-26 15:00       ` Zhang, Helin
2015-05-26 15:02       ` Ananyev, Konstantin
2015-05-26 15:35         ` Stephen Hemminger
2015-05-26 15:46           ` Ananyev, Konstantin
2015-05-27  1:07             ` Zhang, Helin
2015-06-01  8:50     ` Olivier MATZ
2015-06-02  2:37       ` Zhang, Helin
2015-05-26  8:36   ` [dpdk-dev] [PATCH 3/5] i40e: support double vlan stripping and insertion Helin Zhang
2015-06-01  8:50     ` Olivier MATZ
2015-06-02  2:45       ` Zhang, Helin
2015-05-26  8:36   ` [dpdk-dev] [PATCH 4/5] i40evf: add supported offload capability flags Helin Zhang
2015-05-26  8:36   ` [dpdk-dev] [PATCH 5/5] app/testpmd: add test cases for qinq stripping and insertion Helin Zhang
2015-06-02  3:16   ` [dpdk-dev] [PATCH v2 0/6] support i40e QinQ " Helin Zhang
2015-06-02  3:16     ` [dpdk-dev] [PATCH v2 1/6] ixgbe: remove a discarded source line Helin Zhang
2015-06-02  3:16     ` [dpdk-dev] [PATCH v2 2/6] mbuf: use the reserved 16 bits for double vlan Helin Zhang
2015-06-02  3:16     ` [dpdk-dev] [PATCH v2 3/6] i40e: support double vlan stripping and insertion Helin Zhang
2015-06-02  3:16     ` [dpdk-dev] [PATCH v2 4/6] i40evf: add supported offload capability flags Helin Zhang
2015-06-02  3:16     ` Helin Zhang [this message]
2015-06-02  3:16     ` [dpdk-dev] [PATCH v2 6/6] examples/ipv4_multicast: support double vlan stripping and insertion Helin Zhang
2015-06-02  7:37     ` [dpdk-dev] [PATCH v2 0/6] support i40e QinQ " Liu, Jijiang
2015-06-08  7:32       ` Cao, Min
2015-06-08  7:40     ` Olivier MATZ
2015-06-11  7:03     ` [dpdk-dev] [PATCH v3 0/7] " Helin Zhang
2015-06-11  7:03       ` [dpdk-dev] [PATCH v3 1/7] ixgbe: remove a discarded source line Helin Zhang
2015-06-11  7:03       ` [dpdk-dev] [PATCH v3 2/7] mbuf: use the reserved 16 bits for double vlan Helin Zhang
2015-06-25  8:31         ` Zhang, Helin
2015-06-28 20:36           ` Thomas Monjalon
2015-06-30  7:33             ` Olivier MATZ
2015-06-11  7:03       ` [dpdk-dev] [PATCH v3 3/7] i40e: support double vlan stripping and insertion Helin Zhang
2015-06-11  7:03       ` [dpdk-dev] [PATCH v3 4/7] i40evf: add supported offload capability flags Helin Zhang
2015-06-11  7:03       ` [dpdk-dev] [PATCH v3 5/7] app/testpmd: add test cases for qinq stripping and insertion Helin Zhang
2015-06-11  7:03       ` [dpdk-dev] [PATCH v3 6/7] examples/ipv4_multicast: support double vlan " Helin Zhang
2015-06-11  7:04       ` [dpdk-dev] [PATCH v3 7/7] doc: update testpmd command Helin Zhang
2015-06-11  7:25       ` [dpdk-dev] [PATCH v3 0/7] support i40e QinQ stripping and insertion Wu, Jingjing
2015-07-07 14:43         ` Thomas Monjalon

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=1433214967-22247-6-git-send-email-helin.zhang@intel.com \
    --to=helin.zhang@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).