From mboxrd@z Thu Jan  1 00:00:00 1970
Return-Path: <couyang@shecgisg004.sh.intel.com>
Received: from mga11.intel.com (mga11.intel.com [192.55.52.93])
 by dpdk.org (Postfix) with ESMTP id 17E229A8C
 for <dev@dpdk.org>; Mon,  9 Feb 2015 02:15:11 +0100 (CET)
Received: from orsmga002.jf.intel.com ([10.7.209.21])
 by fmsmga102.fm.intel.com with ESMTP; 08 Feb 2015 17:15:10 -0800
X-ExtLoop1: 1
X-IronPort-AV: E=Sophos;i="5.09,540,1418112000"; d="scan'208";a="682851168"
Received: from shvmail01.sh.intel.com ([10.239.29.42])
 by orsmga002.jf.intel.com with ESMTP; 08 Feb 2015 17:15:10 -0800
Received: from shecgisg004.sh.intel.com (shecgisg004.sh.intel.com
 [10.239.29.89])
 by shvmail01.sh.intel.com with ESMTP id t191F7Qc018033;
 Mon, 9 Feb 2015 09:15:07 +0800
Received: from shecgisg004.sh.intel.com (localhost [127.0.0.1])
 by shecgisg004.sh.intel.com (8.13.6/8.13.6/SuSE Linux 0.8) with ESMTP id
 t191F5ax011539; Mon, 9 Feb 2015 09:15:07 +0800
Received: (from couyang@localhost)
 by shecgisg004.sh.intel.com (8.13.6/8.13.6/Submit) id t191F4Bg011535;
 Mon, 9 Feb 2015 09:15:04 +0800
From: Ouyang Changchun <changchun.ouyang@intel.com>
To: dev@dpdk.org
Date: Mon,  9 Feb 2015 09:14:09 +0800
Message-Id: <1423444455-11330-21-git-send-email-changchun.ouyang@intel.com>
X-Mailer: git-send-email 1.7.12.2
In-Reply-To: <1423444455-11330-1-git-send-email-changchun.ouyang@intel.com>
References: <1422516249-14596-1-git-send-email-changchun.ouyang@intel.com>
 <1423444455-11330-1-git-send-email-changchun.ouyang@intel.com>
Subject: [dpdk-dev] [PATCH v4 20/26] example/vhost: Avoid inserting vlan
	twice
X-BeenThere: dev@dpdk.org
X-Mailman-Version: 2.1.15
Precedence: list
List-Id: patches and discussions about DPDK <dev.dpdk.org>
List-Unsubscribe: <http://dpdk.org/ml/options/dev>,
 <mailto:dev-request@dpdk.org?subject=unsubscribe>
List-Archive: <http://dpdk.org/ml/archives/dev/>
List-Post: <mailto:dev@dpdk.org>
List-Help: <mailto:dev-request@dpdk.org?subject=help>
List-Subscribe: <http://dpdk.org/ml/listinfo/dev>,
 <mailto:dev-request@dpdk.org?subject=subscribe>
X-List-Received-Date: Mon, 09 Feb 2015 01:15:12 -0000

Check if it has already been vlan-tagged packet, if true, avoid inserting a
duplicated vlan tag into it.

This is a possible case when guest has the capability of inserting vlan tag.

Signed-off-by: Changchun Ouyang <changchun.ouyang@intel.com>
---
 examples/vhost/main.c | 45 ++++++++++++++++++++++++++++-----------------
 1 file changed, 28 insertions(+), 17 deletions(-)

diff --git a/examples/vhost/main.c b/examples/vhost/main.c
index 04f0118..6af7874 100644
--- a/examples/vhost/main.c
+++ b/examples/vhost/main.c
@@ -1115,6 +1115,7 @@ virtio_tx_route(struct vhost_dev *vdev, struct rte_mbuf *m, uint16_t vlan_tag)
 	unsigned len, ret, offset = 0;
 	const uint16_t lcore_id = rte_lcore_id();
 	struct virtio_net *dev = vdev->dev;
+	struct ether_hdr *nh;
 
 	/*check if destination is local VM*/
 	if ((vm2vm_mode == VM2VM_SOFTWARE) && (virtio_tx_local(vdev, m) == 0)) {
@@ -1135,28 +1136,38 @@ virtio_tx_route(struct vhost_dev *vdev, struct rte_mbuf *m, uint16_t vlan_tag)
 	tx_q = &lcore_tx_queue[lcore_id];
 	len = tx_q->len;
 
-	m->ol_flags = PKT_TX_VLAN_PKT;
+	nh = rte_pktmbuf_mtod(m, struct ether_hdr *);
+	if (unlikely(nh->ether_type == rte_cpu_to_be_16(ETHER_TYPE_VLAN))) {
+		/* Guest has inserted the vlan tag. */
+		struct vlan_hdr *vh = (struct vlan_hdr *) (nh + 1);
+		uint16_t vlan_tag_be = rte_cpu_to_be_16(vlan_tag);
+		if ((vm2vm_mode == VM2VM_HARDWARE) &&
+			(vh->vlan_tci != vlan_tag_be))
+			vh->vlan_tci = vlan_tag_be;
+	} else {
+		m->ol_flags = PKT_TX_VLAN_PKT;
 
-	/*
-	 * Find the right seg to adjust the data len when offset is
-	 * bigger than tail room size.
-	 */
-	if (unlikely(vm2vm_mode == VM2VM_HARDWARE)) {
-		if (likely(offset <= rte_pktmbuf_tailroom(m)))
-			m->data_len += offset;
-		else {
-			struct rte_mbuf *seg = m;
+		/*
+		 * Find the right seg to adjust the data len when offset is
+		 * bigger than tail room size.
+		 */
+		if (unlikely(vm2vm_mode == VM2VM_HARDWARE)) {
+			if (likely(offset <= rte_pktmbuf_tailroom(m)))
+				m->data_len += offset;
+			else {
+				struct rte_mbuf *seg = m;
 
-			while ((seg->next != NULL) &&
-				(offset > rte_pktmbuf_tailroom(seg)))
-				seg = seg->next;
+				while ((seg->next != NULL) &&
+					(offset > rte_pktmbuf_tailroom(seg)))
+					seg = seg->next;
 
-			seg->data_len += offset;
+				seg->data_len += offset;
+			}
+			m->pkt_len += offset;
 		}
-		m->pkt_len += offset;
-	}
 
-	m->vlan_tci = vlan_tag;
+		m->vlan_tci = vlan_tag;
+	}
 
 	tx_q->m_table[len] = m;
 	len++;
-- 
1.8.4.2