linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* in kernel 2.6.x, tun/tap nic supports vlan packets
@ 2014-04-17  3:35 zhuyj
  2014-04-17  5:02 ` Willy Tarreau
                   ` (2 more replies)
  0 siblings, 3 replies; 13+ messages in thread
From: zhuyj @ 2014-04-17  3:35 UTC (permalink / raw)
  To: David S. Miller, netdev, joe, julia.lawall, dingtianhong,
	linux-kernel, jasowang, mst, Willy Tarreau, Yang, Zhangle (Eric),
	Wu, Kuaikuai, Tao, Yue, zhuyj

[-- Attachment #1: Type: text/plain, Size: 1342 bytes --]

Hi, all

In kernel 2.6.x, linux depends on nic vlan hardware acceleration to 
insert/extract
vlan tag. In this scene, in kernel 2.6.x

                  _____        ________
     A           |     | B    |        | C
  vlan packets-->| tap |----->|vlan nic|--->
                 |_____|      |________|

We hope vlan packets pass through tap and vlan nic from A to c.
But in kernel 2.6.x, linux kernel can not extract vlan tag. It depends
on nic vlan hardware acceleration. It is well known that tap nic has no
vlan acceleration. So in the above scene, vlan packets can not be handled by
tap nic. These vlan packets will be discarded in B. They can not arrive 
at C.

In kernel 3.x, linux can handle vlan packets. It does not depend on nic vlan
hardware acceleration. So the above scene can work well in kernel 3.x.

To resolve the above in kernel 2.6.x, we simulated vlan hardware 
acceleration in
tun/tap driver. Then followed the logic of commit commit 4fba4ca4
[vlan: Centralize handling of hardware acceleration] to modify the vlan 
packets
process in kernel 2.6.x. In the end, the above scene can work well in 
patched
kernel 2.6.x.

Please comment on it. Any reply is appreciated.

Hi, Willy

These 2 patches are for linux2.6.x. These can work well here. Please 
help to merge
linux 2.6.32.x. Thanks a lot.

Best Regards!
Zhu Yanjun


[-- Attachment #2: 0001-tun-tap-add-the-feature-of-vlan-rx-extraction.patch --]
[-- Type: text/x-patch, Size: 6341 bytes --]

>From 66db0748fc0f932496100789eb319ca5884c0694 Mon Sep 17 00:00:00 2001
From: Zhu Yanjun <Yanjun.Zhu@windriver.com>
Date: Wed, 16 Apr 2014 18:19:42 +0800
Subject: [PATCH 1/2] tun/tap: add the feature of vlan rx extraction

Tap is a virtual net device that has no vlan rx untag feature.
So this virtual device can not send/receive vlan packets in
kernel 2.6.x. To make this device support vlan send/receive vlan
packets in kernel 2.6.x, a vlan rx extraction feature is simulated
in its driver.

Signed-off-by: Zhu Yanjun <Yanjun.Zhu@windriver.com>
---
 drivers/net/tun.c         |  118 ++++++++++++++++++++++++++++++++++++++++++++-
 include/linux/netdevice.h |    1 +
 net/core/dev.c            |   13 +++++
 3 files changed, 131 insertions(+), 1 deletion(-)

diff --git a/drivers/net/tun.c b/drivers/net/tun.c
index 894ad84..029e6cf 100644
--- a/drivers/net/tun.c
+++ b/drivers/net/tun.c
@@ -69,6 +69,8 @@
 #include <asm/system.h>
 #include <asm/uaccess.h>
 
+#include <linux/if_vlan.h>
+
 /* Uncomment to enable debugging */
 /* #define TUN_DEBUG 1 */
 
@@ -426,6 +428,8 @@ static const struct net_device_ops tun_netdev_ops = {
 	.ndo_change_mtu		= tun_net_change_mtu,
 };
 
+static void tap_vlan_rx_register(struct net_device *dev, struct vlan_group *grp);
+
 static const struct net_device_ops tap_netdev_ops = {
 	.ndo_uninit		= tun_net_uninit,
 	.ndo_open		= tun_net_open,
@@ -435,6 +439,7 @@ static const struct net_device_ops tap_netdev_ops = {
 	.ndo_set_multicast_list	= tun_net_mclist,
 	.ndo_set_mac_address	= eth_mac_addr,
 	.ndo_validate_addr	= eth_validate_addr,
+	.ndo_vlan_rx_register   = tap_vlan_rx_register,
 };
 
 /* Initialize net device. */
@@ -464,6 +469,8 @@ static void tun_net_init(struct net_device *dev)
 
 		random_ether_addr(dev->dev_addr);
 
+		dev->features |= NETIF_F_HW_VLAN_RX;
+
 		dev->tx_queue_len = TUN_READQ_SIZE;  /* We prefer our own queue length */
 		break;
 	}
@@ -530,6 +537,105 @@ static inline struct sk_buff *tun_alloc_skb(struct tun_struct *tun,
 	return skb;
 }
 
+static struct sk_buff *vlan_reorder_header(struct sk_buff *skb)
+{
+	if (skb_cow(skb, skb_headroom(skb)) < 0)
+		return NULL;
+	memmove(skb->data - ETH_HLEN, skb->data - VLAN_ETH_HLEN, 2 * ETH_ALEN);
+	skb->mac_header += VLAN_HLEN;
+	return skb;
+}
+
+static void vlan_set_encap_proto(struct sk_buff *skb, struct vlan_hdr *vhdr)
+{
+	__be16 proto;
+	unsigned char *rawp;
+
+	/*
+ * 	 * Was a VLAN packet, grab the encapsulated protocol, which the layer
+ * 	 	 * three protocols care about.
+ * 	 	 	 */
+
+	proto = vhdr->h_vlan_encapsulated_proto;
+	if (ntohs(proto) >= 1536) {
+		skb->protocol = proto;
+		return;
+	}
+
+	rawp = skb->data;
+	if (*(unsigned short *) rawp == 0xFFFF)
+		/*
+ * 		 * This is a magic hack to spot IPX packets. Older Novell
+ * 		 		 * breaks the protocol design and runs IPX over 802.3 without
+ * 		 		 		 * an 802.2 LLC layer. We look for FFFF which isn't a used
+ * 		 		 		 		 * 802.2 SSAP/DSAP. This won't work for fault tolerant netware
+ * 		 		 		 		 		 * but does for the rest.
+ * 		 		 		 		 		 		 */
+		skb->protocol = htons(ETH_P_802_3);
+	else
+		/*
+ * 		 * Real 802.2 LLC
+ * 		 		 */
+		skb->protocol = htons(ETH_P_802_2);
+}
+
+static void skb_reset_mac_len(struct sk_buff *skb)
+{
+	skb->mac_len = skb->network_header - skb->mac_header;
+}
+
+static struct sk_buff *vlan_untag(struct sk_buff *skb)
+{
+	struct vlan_hdr *vhdr;
+	u16 vlan_tci;
+
+	if (unlikely(vlan_tx_tag_present(skb))) {
+		/* vlan_tci is already set-up so leave this for another time */
+		return skb;
+	}
+
+	skb = skb_share_check(skb, GFP_ATOMIC);
+	if (unlikely(!skb))
+		goto err_free;
+
+	if (unlikely(!pskb_may_pull(skb, VLAN_HLEN)))
+		goto err_free;
+
+	vhdr = (struct vlan_hdr *) skb->data;
+	vlan_tci = ntohs(vhdr->h_vlan_TCI);
+	__vlan_hwaccel_put_tag(skb, vlan_tci);
+
+	skb_pull_rcsum(skb, VLAN_HLEN);
+	vlan_set_encap_proto(skb, vhdr);
+
+	skb = vlan_reorder_header(skb);
+	if (unlikely(!skb))
+		goto err_free;
+
+	skb_reset_network_header(skb);
+	skb_reset_transport_header(skb);
+	skb_reset_mac_len(skb);
+
+	return skb;
+
+err_free:
+	kfree_skb(skb);
+	return NULL;
+}
+
+static struct vlan_group *g_vlgrp = NULL;
+static void tap_vlan_rx_register(struct net_device *dev,
+		struct vlan_group *grp)
+{
+	unsigned long flags;
+	local_irq_save(flags);
+
+	printk(KERN_DEBUG "zhuyj func:%s,line:%d\n", __FUNCTION__, __LINE__);
+	g_vlgrp = grp;
+	tun_net_change_mtu(dev, dev->mtu);
+	local_irq_restore(flags);
+}
+
 /* Get packet from user space buffer */
 static __inline__ ssize_t tun_get_user(struct tun_struct *tun,
 				       const struct iovec *iv, size_t count,
@@ -655,7 +761,17 @@ static __inline__ ssize_t tun_get_user(struct tun_struct *tun,
 		skb_shinfo(skb)->gso_segs = 0;
 	}
 
-	netif_rx_ni(skb);
+	if (g_vlgrp && (skb->protocol == cpu_to_be16(ETH_P_8021Q))){
+		struct vlan_hdr *vhdr;
+		u16 vlan_tci;
+		int ret;
+		vhdr = (struct vlan_hdr *) skb->data;
+		vlan_tci = ntohs(vhdr->h_vlan_TCI);
+		skb = vlan_untag(skb);
+		ret = vlan_netif_rx(skb, g_vlgrp, vlan_tci);
+	} else {
+		netif_rx_ni(skb);
+	}
 
 	tun->dev->stats.rx_packets++;
 	tun->dev->stats.rx_bytes += len;
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 9d7e8f7..04c659b 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -1467,6 +1467,7 @@ extern void dev_kfree_skb_any(struct sk_buff *skb);
 #define HAVE_NETIF_RX 1
 extern int		netif_rx(struct sk_buff *skb);
 extern int		netif_rx_ni(struct sk_buff *skb);
+extern int		vlan_netif_rx(struct sk_buff *skb, struct vlan_group *grp, u16 vlan_tci);
 #define HAVE_NETIF_RECEIVE_SKB 1
 extern int		netif_receive_skb(struct sk_buff *skb);
 extern void		napi_gro_flush(struct napi_struct *napi);
diff --git a/net/core/dev.c b/net/core/dev.c
index d775563..a3802ca 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -2067,6 +2067,19 @@ int netif_rx_ni(struct sk_buff *skb)
 }
 EXPORT_SYMBOL(netif_rx_ni);
 
+int vlan_netif_rx(struct sk_buff *skb, struct vlan_group *grp, u16 vlan_tci)
+{
+	int ret;
+
+	preempt_disable();
+	ret = __vlan_hwaccel_rx(skb, grp, vlan_tci, 0);
+	if (local_softirq_pending())
+		do_softirq();
+	preempt_enable();
+	return ret;
+}
+EXPORT_SYMBOL(vlan_netif_rx);
+
 static void net_tx_action(struct softirq_action *h)
 {
 	struct softnet_data *sd = &__get_cpu_var(softnet_data);
-- 
1.7.9.5


[-- Attachment #3: 0002-vlan-Centralize-handling-of-hardware-acceleration.patch --]
[-- Type: text/x-patch, Size: 9907 bytes --]

>From 86fff983b7f36750301aab537dfd4e5744d929e7 Mon Sep 17 00:00:00 2001
From: Zhu Yanjun <Yanjun.Zhu@windriver.com>
Date: Wed, 16 Apr 2014 18:57:23 +0800
Subject: [PATCH 2/2] vlan: Centralize handling of hardware acceleration

2.6.x kernels require a similar logic change as commit 4fba4ca4
[vlan: Centralize handling of hardware acceleration] introduces
for newer kernels.

Since there is something wrong with sending/receiving vlan packets
of tun/tap of kernel 2.6.x. In kernel(3.0+), sending/receiving
vlan packets is centralize handling in kernel. But in kernel 2.6.x,
inserting/extraction vlan tag is still based on nic hardware. Thus,
tun/tap nic driver can not support vlan packets. It is necessary
to centralize handling of hardware acceleration and simulate vlan
rx extraction in tun/tap nic driver to make tun/tap support vlan
packets sending/receiving in kernel 2.6.x.

Signed-off-by: Zhu Yanjun <Yanjun.Zhu@windriver.com>
---
 include/linux/if_vlan.h   |    4 +-
 include/linux/netdevice.h |    1 -
 net/8021q/vlan.c          |   49 ++++++++++++++++++++
 net/8021q/vlan_core.c     |  110 +++++----------------------------------------
 net/core/dev.c            |   42 +++++++----------
 5 files changed, 76 insertions(+), 130 deletions(-)

diff --git a/include/linux/if_vlan.h b/include/linux/if_vlan.h
index 7ff9af1..5538dda 100644
--- a/include/linux/if_vlan.h
+++ b/include/linux/if_vlan.h
@@ -114,7 +114,7 @@ extern u16 vlan_dev_vlan_id(const struct net_device *dev);
 
 extern int __vlan_hwaccel_rx(struct sk_buff *skb, struct vlan_group *grp,
 			     u16 vlan_tci, int polling);
-extern int vlan_hwaccel_do_receive(struct sk_buff *skb);
+extern bool vlan_hwaccel_do_receive(struct sk_buff **skb);
 extern int vlan_gro_receive(struct napi_struct *napi, struct vlan_group *grp,
 			    unsigned int vlan_tci, struct sk_buff *skb);
 extern int vlan_gro_frags(struct napi_struct *napi, struct vlan_group *grp,
@@ -140,7 +140,7 @@ static inline int __vlan_hwaccel_rx(struct sk_buff *skb, struct vlan_group *grp,
 	return NET_XMIT_SUCCESS;
 }
 
-static inline int vlan_hwaccel_do_receive(struct sk_buff *skb)
+static inline bool vlan_hwaccel_do_receive(struct sk_buff **skb)
 {
 	return 0;
 }
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 04c659b..bdb6b82 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -1490,7 +1490,6 @@ static inline void napi_free_frags(struct napi_struct *napi)
 	napi->skb = NULL;
 }
 
-extern void		netif_nit_deliver(struct sk_buff *skb);
 extern int		dev_valid_name(const char *name);
 extern int		dev_ioctl(struct net *net, unsigned int cmd, void __user *);
 extern int		dev_ethtool(struct net *net, struct ifreq *);
diff --git a/net/8021q/vlan.c b/net/8021q/vlan.c
index a29c5ab..385c6e4 100644
--- a/net/8021q/vlan.c
+++ b/net/8021q/vlan.c
@@ -92,6 +92,54 @@ struct net_device *__find_vlan_dev(struct net_device *real_dev, u16 vlan_id)
 	return NULL;
 }
 
+bool vlan_hwaccel_do_receive(struct sk_buff **skbp)
+{
+	struct sk_buff *skb = *skbp;
+	u16 vlan_id = skb->vlan_tci & VLAN_VID_MASK;
+	struct net_device *vlan_dev;
+	struct vlan_rx_stats *rx_stats;
+
+	vlan_dev = __find_vlan_dev(skb->dev, vlan_id);
+	if (!vlan_dev) {
+		if (vlan_id)
+			skb->pkt_type = PACKET_OTHERHOST;
+		return false;
+	}
+
+	skb = *skbp = skb_share_check(skb, GFP_ATOMIC);
+	if (unlikely(!skb))
+		return false;
+
+	skb->dev = vlan_dev;
+	skb->priority = vlan_get_ingress_priority(vlan_dev, skb->vlan_tci);
+	skb->vlan_tci = 0;
+
+	rx_stats = per_cpu_ptr(vlan_dev_info(vlan_dev)->vlan_rx_stats,
+				smp_processor_id());
+
+	rx_stats->rx_packets++;
+	rx_stats->rx_bytes += skb->len;
+
+	switch (skb->pkt_type) {
+	case PACKET_BROADCAST:
+		break;
+	case PACKET_MULTICAST:
+		rx_stats->multicast++;
+		break;
+	case PACKET_OTHERHOST:
+		/* Our lower layer thinks this is not local, let's make sure.
+		 * This allows the VLAN to have a different MAC than the
+		 * underlying device, and still route correctly. */
+		if (!compare_ether_addr(eth_hdr(skb)->h_dest,
+					vlan_dev->dev_addr))
+			skb->pkt_type = PACKET_HOST;
+			break;
+	};
+
+	return true;
+}
+extern bool (*__vlan_do_receive)(struct sk_buff **skbp);
+
 static void vlan_group_free(struct vlan_group *grp)
 {
 	int i;
@@ -744,6 +792,7 @@ static int __init vlan_proto_init(void)
 
 	dev_add_pack(&vlan_packet_type);
 	vlan_ioctl_set(vlan_ioctl_handler);
+	__vlan_do_receive = vlan_hwaccel_do_receive;
 	return 0;
 
 err4:
diff --git a/net/8021q/vlan_core.c b/net/8021q/vlan_core.c
index 7f7de1a..c679535 100644
--- a/net/8021q/vlan_core.c
+++ b/net/8021q/vlan_core.c
@@ -4,64 +4,6 @@
 #include <linux/netpoll.h>
 #include "vlan.h"
 
-/* VLAN rx hw acceleration helper.  This acts like netif_{rx,receive_skb}(). */
-int __vlan_hwaccel_rx(struct sk_buff *skb, struct vlan_group *grp,
-		      u16 vlan_tci, int polling)
-{
-	if (netpoll_rx(skb))
-		return NET_RX_DROP;
-
-	if (skb_bond_should_drop(skb))
-		goto drop;
-
-	skb->vlan_tci = vlan_tci;
-	skb->dev = vlan_group_get_device(grp, vlan_tci & VLAN_VID_MASK);
-
-	if (!skb->dev)
-		goto drop;
-
-	return (polling ? netif_receive_skb(skb) : netif_rx(skb));
-
-drop:
-	dev_kfree_skb_any(skb);
-	return NET_RX_DROP;
-}
-EXPORT_SYMBOL(__vlan_hwaccel_rx);
-
-int vlan_hwaccel_do_receive(struct sk_buff *skb)
-{
-	struct net_device *dev = skb->dev;
-	struct net_device_stats *stats;
-
-	skb->dev = vlan_dev_info(dev)->real_dev;
-	netif_nit_deliver(skb);
-
-	skb->dev = dev;
-	skb->priority = vlan_get_ingress_priority(dev, skb->vlan_tci);
-	skb->vlan_tci = 0;
-
-	stats = &dev->stats;
-	stats->rx_packets++;
-	stats->rx_bytes += skb->len;
-
-	switch (skb->pkt_type) {
-	case PACKET_BROADCAST:
-		break;
-	case PACKET_MULTICAST:
-		stats->multicast++;
-		break;
-	case PACKET_OTHERHOST:
-		/* Our lower layer thinks this is not local, let's make sure.
-		 * This allows the VLAN to have a different MAC than the
-		 * underlying device, and still route correctly. */
-		if (!compare_ether_addr(eth_hdr(skb)->h_dest,
-					dev->dev_addr))
-			skb->pkt_type = PACKET_HOST;
-		break;
-	};
-	return 0;
-}
-
 struct net_device *vlan_dev_real_dev(const struct net_device *dev)
 {
 	return vlan_dev_info(dev)->real_dev;
@@ -74,59 +16,27 @@ u16 vlan_dev_vlan_id(const struct net_device *dev)
 }
 EXPORT_SYMBOL(vlan_dev_vlan_id);
 
-static int vlan_gro_common(struct napi_struct *napi, struct vlan_group *grp,
-			   unsigned int vlan_tci, struct sk_buff *skb)
+/* VLAN rx hw acceleration helper.  This acts like netif_{rx,receive_skb}(). */
+int __vlan_hwaccel_rx(struct sk_buff *skb, struct vlan_group *grp,
+			u16 vlan_tci, int polling)
 {
-	struct sk_buff *p;
-
-	if (skb_bond_should_drop(skb))
-		goto drop;
-
-	skb->vlan_tci = vlan_tci;
-	skb->dev = vlan_group_get_device(grp, vlan_tci & VLAN_VID_MASK);
-
-	if (!skb->dev)
-		goto drop;
-
-	for (p = napi->gro_list; p; p = p->next) {
-		NAPI_GRO_CB(p)->same_flow =
-			p->dev == skb->dev && !compare_ether_header(
-				skb_mac_header(p), skb_gro_mac_header(skb));
-		NAPI_GRO_CB(p)->flush = 0;
-	}
-
-	return dev_gro_receive(napi, skb);
-
-drop:
-	return GRO_DROP;
+	__vlan_hwaccel_put_tag(skb, vlan_tci);
+	return polling ? netif_receive_skb(skb) : netif_rx(skb); 
 }
+EXPORT_SYMBOL(__vlan_hwaccel_rx);
 
 int vlan_gro_receive(struct napi_struct *napi, struct vlan_group *grp,
 		     unsigned int vlan_tci, struct sk_buff *skb)
 {
-	if (netpoll_rx_on(skb))
-		return vlan_hwaccel_receive_skb(skb, grp, vlan_tci);
-
-	skb_gro_reset_offset(skb);
-
-	return napi_skb_finish(vlan_gro_common(napi, grp, vlan_tci, skb), skb);
+	__vlan_hwaccel_put_tag(skb, vlan_tci);
+	return napi_gro_receive(napi, skb);
 }
 EXPORT_SYMBOL(vlan_gro_receive);
 
 int vlan_gro_frags(struct napi_struct *napi, struct vlan_group *grp,
 		   unsigned int vlan_tci)
 {
-	struct sk_buff *skb = napi_frags_skb(napi);
-
-	if (!skb)
-		return NET_RX_DROP;
-
-	if (netpoll_rx_on(skb)) {
-		skb->protocol = eth_type_trans(skb, skb->dev);
-		return vlan_hwaccel_receive_skb(skb, grp, vlan_tci);
-	}
-
-	return napi_frags_finish(napi, skb,
-				 vlan_gro_common(napi, grp, vlan_tci, skb));
+	__vlan_hwaccel_put_tag(napi->skb, vlan_tci);
+	return napi_gro_frags(napi);
 }
 EXPORT_SYMBOL(vlan_gro_frags);
diff --git a/net/core/dev.c b/net/core/dev.c
index a3802ca..b69487e 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -2272,33 +2272,8 @@ out:
 }
 #endif
 
-/*
- * 	netif_nit_deliver - deliver received packets to network taps
- * 	@skb: buffer
- *
- * 	This function is used to deliver incoming packets to network
- * 	taps. It should be used when the normal netif_receive_skb path
- * 	is bypassed, for example because of VLAN acceleration.
- */
-void netif_nit_deliver(struct sk_buff *skb)
-{
-	struct packet_type *ptype;
-
-	if (list_empty(&ptype_all))
-		return;
-
-	skb_reset_network_header(skb);
-	skb_reset_transport_header(skb);
-	skb->mac_len = skb->network_header - skb->mac_header;
-
-	rcu_read_lock();
-	list_for_each_entry_rcu(ptype, &ptype_all, list) {
-		if (!ptype->dev || ptype->dev == skb->dev)
-			deliver_skb(skb, ptype, skb->dev);
-	}
-	rcu_read_unlock();
-}
-
+bool (*__vlan_do_receive)(struct sk_buff **skbp) = NULL;
+EXPORT_SYMBOL(__vlan_do_receive);
 /**
  *	netif_receive_skb - process receive buffer from network
  *	@skb: buffer to process
@@ -2354,6 +2329,8 @@ int netif_receive_skb(struct sk_buff *skb)
 
 	rcu_read_lock();
 
+another_round:
+
 #ifdef CONFIG_NET_CLS_ACT
 	if (skb->tc_verd & TC_NCLS) {
 		skb->tc_verd = CLR_TC_NCLS(skb->tc_verd);
@@ -2377,6 +2354,17 @@ int netif_receive_skb(struct sk_buff *skb)
 ncls:
 #endif
 
+	if (vlan_tx_tag_present(skb)) {
+		if (pt_prev) {
+			ret = deliver_skb(skb, pt_prev, orig_dev);
+			pt_prev = NULL;
+		}
+		if (__vlan_do_receive && __vlan_do_receive(&skb)) {
+			goto another_round;
+		} else if (unlikely(!skb))
+			goto out;
+	}
+
 	skb = handle_bridge(skb, &pt_prev, &ret, orig_dev);
 	if (!skb)
 		goto out;
-- 
1.7.9.5


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

* Re: in kernel 2.6.x, tun/tap nic supports vlan packets
  2014-04-17  3:35 in kernel 2.6.x, tun/tap nic supports vlan packets zhuyj
@ 2014-04-17  5:02 ` Willy Tarreau
  2014-04-17  5:50   ` zhuyj
                     ` (2 more replies)
  2014-04-17  6:27 ` zhuyj
  2014-04-17 13:52 ` zhuyj
  2 siblings, 3 replies; 13+ messages in thread
From: Willy Tarreau @ 2014-04-17  5:02 UTC (permalink / raw)
  To: zhuyj
  Cc: David S. Miller, netdev, joe, julia.lawall, dingtianhong,
	linux-kernel, jasowang, mst, Yang, Zhangle (Eric),
	Wu, Kuaikuai, Tao, Yue

Hi Zhu,

On Thu, Apr 17, 2014 at 11:35:58AM +0800, zhuyj wrote:
> Hi, all
> 
> In kernel 2.6.x, linux depends on nic vlan hardware acceleration to 
> insert/extract
> vlan tag. In this scene, in kernel 2.6.x
> 
>                  _____        ________
>     A           |     | B    |        | C
>  vlan packets-->| tap |----->|vlan nic|--->
>                 |_____|      |________|
> 
> We hope vlan packets pass through tap and vlan nic from A to c.
> But in kernel 2.6.x, linux kernel can not extract vlan tag. It depends
> on nic vlan hardware acceleration. It is well known that tap nic has no
> vlan acceleration. So in the above scene, vlan packets can not be handled by
> tap nic. These vlan packets will be discarded in B. They can not arrive 
> at C.

It's not clear to me what you want to achieve. Are you trying to create
vlan interfaces on top of a tap interface ? Eg: tap1.12, tap1.23 etc ?

> In kernel 3.x, linux can handle vlan packets. It does not depend on nic vlan
> hardware acceleration. So the above scene can work well in kernel 3.x.
> 
> To resolve the above in kernel 2.6.x, we simulated vlan hardware 
> acceleration in
> tun/tap driver. Then followed the logic of commit commit 4fba4ca4
> [vlan: Centralize handling of hardware acceleration] to modify the vlan 
> packets
> process in kernel 2.6.x. In the end, the above scene can work well in 
> patched
> kernel 2.6.x.
> 
> Please comment on it. Any reply is appreciated.
> 
> Hi, Willy
> 
> These 2 patches are for linux2.6.x. These can work well here. Please 
> help to merge
> linux 2.6.32.x. Thanks a lot.

Well, 2.6.32.x is in deep freeze mode and it receives only critical fixes
once in a while. While I can appreciate that the patch above might solve
the issue you're facing, I'm wondering if there are not any acceptable
workarounds for such a deep freeze kernel. You patch is not huge, but it
definitely affects a working driver, and I wouldn't like risking to break
the tap driver for other users, and I reall don't have the skills to audit
it completely to ensure this is not the case. And if it breaks, I'll have
to revert it or seek for some help on netdev.

So I'd say that I'd rather not merge it unless I get an Acked-by from some
netdev people who are willing to help in case of any future regression,
which is unlikely but still possible.

Just out of curiosity, what is the motivation for ongoing development on
top of 2.6.32 ? Are there any important deployments that cannot upgrade
for any specific reason ? I'm asking because most 2.6.32.x kernels that
are stuffed into embedded boxes very likely come with their own number
of in-house patches to add whatever feature is needed in such contexts,
so I'm wondering why having this patch in mainline would help in your
situation compared to having it into your own patch set only.

Thanks,
Willy


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

* Re: in kernel 2.6.x, tun/tap nic supports vlan packets
  2014-04-17  5:02 ` Willy Tarreau
@ 2014-04-17  5:50   ` zhuyj
  2014-04-19 13:43   ` zhuyj
  2014-04-22 17:53   ` Ben Hutchings
  2 siblings, 0 replies; 13+ messages in thread
From: zhuyj @ 2014-04-17  5:50 UTC (permalink / raw)
  To: Willy Tarreau
  Cc: David S. Miller, netdev, joe, julia.lawall, dingtianhong,
	linux-kernel, jasowang, mst, Yang, Zhangle (Eric),
	Wu, Kuaikuai, Tao, Yue, zhuyj

On 04/17/2014 01:02 PM, Willy Tarreau wrote:
> Hi Zhu,
>
> On Thu, Apr 17, 2014 at 11:35:58AM +0800, zhuyj wrote:
>> Hi, all
>>
>> In kernel 2.6.x, linux depends on nic vlan hardware acceleration to
>> insert/extract
>> vlan tag. In this scene, in kernel 2.6.x
>>
>>                   _____        ________
>>      A           |     | B    |        | C
>>   vlan packets-->| tap |----->|vlan nic|--->
>>                  |_____|      |________|
>>
>> We hope vlan packets pass through tap and vlan nic from A to c.
>> But in kernel 2.6.x, linux kernel can not extract vlan tag. It depends
>> on nic vlan hardware acceleration. It is well known that tap nic has no
>> vlan acceleration. So in the above scene, vlan packets can not be handled by
>> tap nic. These vlan packets will be discarded in B. They can not arrive
>> at C.
> It's not clear to me what you want to achieve. Are you trying to create
> vlan interfaces on top of a tap interface ? Eg: tap1.12, tap1.23 etc ?
Hi, Willy

Yes. These 2 patches are trying create vlan interfaces on top of a tap 
interface.

Zhu Yanjun
>
>> In kernel 3.x, linux can handle vlan packets. It does not depend on nic vlan
>> hardware acceleration. So the above scene can work well in kernel 3.x.
>>
>> To resolve the above in kernel 2.6.x, we simulated vlan hardware
>> acceleration in
>> tun/tap driver. Then followed the logic of commit commit 4fba4ca4
>> [vlan: Centralize handling of hardware acceleration] to modify the vlan
>> packets
>> process in kernel 2.6.x. In the end, the above scene can work well in
>> patched
>> kernel 2.6.x.
>>
>> Please comment on it. Any reply is appreciated.
>>
>> Hi, Willy
>>
>> These 2 patches are for linux2.6.x. These can work well here. Please
>> help to merge
>> linux 2.6.32.x. Thanks a lot.
> Well, 2.6.32.x is in deep freeze mode and it receives only critical fixes
> once in a while. While I can appreciate that the patch above might solve
> the issue you're facing, I'm wondering if there are not any acceptable
> workarounds for such a deep freeze kernel. You patch is not huge, but it
> definitely affects a working driver, and I wouldn't like risking to break
> the tap driver for other users, and I reall don't have the skills to audit
> it completely to ensure this is not the case. And if it breaks, I'll have
> to revert it or seek for some help on netdev.
>
> So I'd say that I'd rather not merge it unless I get an Acked-by from some
> netdev people who are willing to help in case of any future regression,
> which is unlikely but still possible.
>
> Just out of curiosity, what is the motivation for ongoing development on
> top of 2.6.32 ? Are there any important deployments that cannot upgrade
> for any specific reason ? I'm asking because most 2.6.32.x kernels that
> are stuffed into embedded boxes very likely come with their own number
> of in-house patches to add whatever feature is needed in such contexts,
> so I'm wondering why having this patch in mainline would help in your
> situation compared to having it into your own patch set only.
>
> Thanks,
> Willy
>
>


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

* Re: in kernel 2.6.x, tun/tap nic supports vlan packets
  2014-04-17  3:35 in kernel 2.6.x, tun/tap nic supports vlan packets zhuyj
  2014-04-17  5:02 ` Willy Tarreau
@ 2014-04-17  6:27 ` zhuyj
  2014-04-17 13:52 ` zhuyj
  2 siblings, 0 replies; 13+ messages in thread
From: zhuyj @ 2014-04-17  6:27 UTC (permalink / raw)
  To: Tao, Yue, linux-kernel, jasowang, Willy Tarreau, Yang,
	Zhangle (Eric),
	zhuyj

Hi, Jaso

Would you like to code review these 2 patches?

Thanks a lot.
Zhu Yanjun
On 04/17/2014 11:35 AM, zhuyj wrote:
> Hi, all
>
> In kernel 2.6.x, linux depends on nic vlan hardware acceleration to 
> insert/extract
> vlan tag. In this scene, in kernel 2.6.x
>
>                  _____        ________
>     A           |     | B    |        | C
>  vlan packets-->| tap |----->|vlan nic|--->
>                 |_____|      |________|
>
> We hope vlan packets pass through tap and vlan nic from A to c.
> But in kernel 2.6.x, linux kernel can not extract vlan tag. It depends
> on nic vlan hardware acceleration. It is well known that tap nic has no
> vlan acceleration. So in the above scene, vlan packets can not be 
> handled by
> tap nic. These vlan packets will be discarded in B. They can not 
> arrive at C.
>
> In kernel 3.x, linux can handle vlan packets. It does not depend on 
> nic vlan
> hardware acceleration. So the above scene can work well in kernel 3.x.
>
> To resolve the above in kernel 2.6.x, we simulated vlan hardware 
> acceleration in
> tun/tap driver. Then followed the logic of commit commit 4fba4ca4
> [vlan: Centralize handling of hardware acceleration] to modify the 
> vlan packets
> process in kernel 2.6.x. In the end, the above scene can work well in 
> patched
> kernel 2.6.x.
>
> Please comment on it. Any reply is appreciated.
>
> Hi, Willy
>
> These 2 patches are for linux2.6.x. These can work well here. Please 
> help to merge
> linux 2.6.32.x. Thanks a lot.
>
> Best Regards!
> Zhu Yanjun
>


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

* Re: in kernel 2.6.x, tun/tap nic supports vlan packets
  2014-04-17  3:35 in kernel 2.6.x, tun/tap nic supports vlan packets zhuyj
  2014-04-17  5:02 ` Willy Tarreau
  2014-04-17  6:27 ` zhuyj
@ 2014-04-17 13:52 ` zhuyj
  2014-04-17 14:23   ` Willy Tarreau
  2 siblings, 1 reply; 13+ messages in thread
From: zhuyj @ 2014-04-17 13:52 UTC (permalink / raw)
  To: David S. Miller, netdev, joe, julia.lawall, dingtianhong,
	linux-kernel, jasowang, mst, Willy Tarreau, Yang, Zhangle (Eric),
	Wu, Kuaikuai, Tao, Yue

[-- Attachment #1: Type: text/plain, Size: 1708 bytes --]

Although the maintainer will not merge these 2 patches, I still fix the 
mistakes in these 2 patches. Now the latest patches are in attachment. 
Maybe these patches can help others.

The latest patches fix mistakes in rx stats.

Best Regards!
Zhu Yanjun
On 04/17/2014 11:35 AM, zhuyj wrote:
> Hi, all
>
> In kernel 2.6.x, linux depends on nic vlan hardware acceleration to 
> insert/extract
> vlan tag. In this scene, in kernel 2.6.x
>
>                  _____        ________
>     A           |     | B    |        | C
>  vlan packets-->| tap |----->|vlan nic|--->
>                 |_____|      |________|
>
> We hope vlan packets pass through tap and vlan nic from A to c.
> But in kernel 2.6.x, linux kernel can not extract vlan tag. It depends
> on nic vlan hardware acceleration. It is well known that tap nic has no
> vlan acceleration. So in the above scene, vlan packets can not be 
> handled by
> tap nic. These vlan packets will be discarded in B. They can not 
> arrive at C.
>
> In kernel 3.x, linux can handle vlan packets. It does not depend on 
> nic vlan
> hardware acceleration. So the above scene can work well in kernel 3.x.
>
> To resolve the above in kernel 2.6.x, we simulated vlan hardware 
> acceleration in
> tun/tap driver. Then followed the logic of commit commit 4fba4ca4
> [vlan: Centralize handling of hardware acceleration] to modify the 
> vlan packets
> process in kernel 2.6.x. In the end, the above scene can work well in 
> patched
> kernel 2.6.x.
>
> Please comment on it. Any reply is appreciated.
>
> Hi, Willy
>
> These 2 patches are for linux2.6.x. These can work well here. Please 
> help to merge
> linux 2.6.32.x. Thanks a lot.
>
> Best Regards!
> Zhu Yanjun
>


[-- Attachment #2: 0001-tun-tap-add-the-feature-of-vlan-rx-extraction.patch --]
[-- Type: text/x-patch, Size: 6340 bytes --]

>From 66db0748fc0f932496100789eb319ca5884c0694 Mon Sep 17 00:00:00 2001
From: root <root@wind-OptiPlex-780.(none)>
Date: Wed, 16 Apr 2014 18:19:42 +0800
Subject: [PATCH 1/2] tun/tap: add the feature of vlan rx extraction

Tap is a virtual net device that has no vlan rx untag feature.
So this virtual device can not send/receive vlan packets in
kernel 2.6.x. To make this device support vlan send/receive vlan
packets in kernel 2.6.x, a vlan rx extraction feature is simulated
in its driver.

Signed-off-by: Zhu Yanjun <Yanjun.Zhu@windriver.com>
---
 drivers/net/tun.c         |  118 ++++++++++++++++++++++++++++++++++++++++++++-
 include/linux/netdevice.h |    1 +
 net/core/dev.c            |   13 +++++
 3 files changed, 131 insertions(+), 1 deletion(-)

diff --git a/drivers/net/tun.c b/drivers/net/tun.c
index 894ad84..029e6cf 100644
--- a/drivers/net/tun.c
+++ b/drivers/net/tun.c
@@ -69,6 +69,8 @@
 #include <asm/system.h>
 #include <asm/uaccess.h>
 
+#include <linux/if_vlan.h>
+
 /* Uncomment to enable debugging */
 /* #define TUN_DEBUG 1 */
 
@@ -426,6 +428,8 @@ static const struct net_device_ops tun_netdev_ops = {
 	.ndo_change_mtu		= tun_net_change_mtu,
 };
 
+static void tap_vlan_rx_register(struct net_device *dev, struct vlan_group *grp);
+
 static const struct net_device_ops tap_netdev_ops = {
 	.ndo_uninit		= tun_net_uninit,
 	.ndo_open		= tun_net_open,
@@ -435,6 +439,7 @@ static const struct net_device_ops tap_netdev_ops = {
 	.ndo_set_multicast_list	= tun_net_mclist,
 	.ndo_set_mac_address	= eth_mac_addr,
 	.ndo_validate_addr	= eth_validate_addr,
+	.ndo_vlan_rx_register   = tap_vlan_rx_register,
 };
 
 /* Initialize net device. */
@@ -464,6 +469,8 @@ static void tun_net_init(struct net_device *dev)
 
 		random_ether_addr(dev->dev_addr);
 
+		dev->features |= NETIF_F_HW_VLAN_RX;
+
 		dev->tx_queue_len = TUN_READQ_SIZE;  /* We prefer our own queue length */
 		break;
 	}
@@ -530,6 +537,105 @@ static inline struct sk_buff *tun_alloc_skb(struct tun_struct *tun,
 	return skb;
 }
 
+static struct sk_buff *vlan_reorder_header(struct sk_buff *skb)
+{
+	if (skb_cow(skb, skb_headroom(skb)) < 0)
+		return NULL;
+	memmove(skb->data - ETH_HLEN, skb->data - VLAN_ETH_HLEN, 2 * ETH_ALEN);
+	skb->mac_header += VLAN_HLEN;
+	return skb;
+}
+
+static void vlan_set_encap_proto(struct sk_buff *skb, struct vlan_hdr *vhdr)
+{
+	__be16 proto;
+	unsigned char *rawp;
+
+	/*
+ * 	 * Was a VLAN packet, grab the encapsulated protocol, which the layer
+ * 	 	 * three protocols care about.
+ * 	 	 	 */
+
+	proto = vhdr->h_vlan_encapsulated_proto;
+	if (ntohs(proto) >= 1536) {
+		skb->protocol = proto;
+		return;
+	}
+
+	rawp = skb->data;
+	if (*(unsigned short *) rawp == 0xFFFF)
+		/*
+ * 		 * This is a magic hack to spot IPX packets. Older Novell
+ * 		 		 * breaks the protocol design and runs IPX over 802.3 without
+ * 		 		 		 * an 802.2 LLC layer. We look for FFFF which isn't a used
+ * 		 		 		 		 * 802.2 SSAP/DSAP. This won't work for fault tolerant netware
+ * 		 		 		 		 		 * but does for the rest.
+ * 		 		 		 		 		 		 */
+		skb->protocol = htons(ETH_P_802_3);
+	else
+		/*
+ * 		 * Real 802.2 LLC
+ * 		 		 */
+		skb->protocol = htons(ETH_P_802_2);
+}
+
+static void skb_reset_mac_len(struct sk_buff *skb)
+{
+	skb->mac_len = skb->network_header - skb->mac_header;
+}
+
+static struct sk_buff *vlan_untag(struct sk_buff *skb)
+{
+	struct vlan_hdr *vhdr;
+	u16 vlan_tci;
+
+	if (unlikely(vlan_tx_tag_present(skb))) {
+		/* vlan_tci is already set-up so leave this for another time */
+		return skb;
+	}
+
+	skb = skb_share_check(skb, GFP_ATOMIC);
+	if (unlikely(!skb))
+		goto err_free;
+
+	if (unlikely(!pskb_may_pull(skb, VLAN_HLEN)))
+		goto err_free;
+
+	vhdr = (struct vlan_hdr *) skb->data;
+	vlan_tci = ntohs(vhdr->h_vlan_TCI);
+	__vlan_hwaccel_put_tag(skb, vlan_tci);
+
+	skb_pull_rcsum(skb, VLAN_HLEN);
+	vlan_set_encap_proto(skb, vhdr);
+
+	skb = vlan_reorder_header(skb);
+	if (unlikely(!skb))
+		goto err_free;
+
+	skb_reset_network_header(skb);
+	skb_reset_transport_header(skb);
+	skb_reset_mac_len(skb);
+
+	return skb;
+
+err_free:
+	kfree_skb(skb);
+	return NULL;
+}
+
+static struct vlan_group *g_vlgrp = NULL;
+static void tap_vlan_rx_register(struct net_device *dev,
+		struct vlan_group *grp)
+{
+	unsigned long flags;
+	local_irq_save(flags);
+
+	printk(KERN_DEBUG "zhuyj func:%s,line:%d\n", __FUNCTION__, __LINE__);
+	g_vlgrp = grp;
+	tun_net_change_mtu(dev, dev->mtu);
+	local_irq_restore(flags);
+}
+
 /* Get packet from user space buffer */
 static __inline__ ssize_t tun_get_user(struct tun_struct *tun,
 				       const struct iovec *iv, size_t count,
@@ -655,7 +761,17 @@ static __inline__ ssize_t tun_get_user(struct tun_struct *tun,
 		skb_shinfo(skb)->gso_segs = 0;
 	}
 
-	netif_rx_ni(skb);
+	if (g_vlgrp && (skb->protocol == cpu_to_be16(ETH_P_8021Q))){
+		struct vlan_hdr *vhdr;
+		u16 vlan_tci;
+		int ret;
+		vhdr = (struct vlan_hdr *) skb->data;
+		vlan_tci = ntohs(vhdr->h_vlan_TCI);
+		skb = vlan_untag(skb);
+		ret = vlan_netif_rx(skb, g_vlgrp, vlan_tci);
+	} else {
+		netif_rx_ni(skb);
+	}
 
 	tun->dev->stats.rx_packets++;
 	tun->dev->stats.rx_bytes += len;
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 9d7e8f7..04c659b 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -1467,6 +1467,7 @@ extern void dev_kfree_skb_any(struct sk_buff *skb);
 #define HAVE_NETIF_RX 1
 extern int		netif_rx(struct sk_buff *skb);
 extern int		netif_rx_ni(struct sk_buff *skb);
+extern int		vlan_netif_rx(struct sk_buff *skb, struct vlan_group *grp, u16 vlan_tci);
 #define HAVE_NETIF_RECEIVE_SKB 1
 extern int		netif_receive_skb(struct sk_buff *skb);
 extern void		napi_gro_flush(struct napi_struct *napi);
diff --git a/net/core/dev.c b/net/core/dev.c
index d775563..a3802ca 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -2067,6 +2067,19 @@ int netif_rx_ni(struct sk_buff *skb)
 }
 EXPORT_SYMBOL(netif_rx_ni);
 
+int vlan_netif_rx(struct sk_buff *skb, struct vlan_group *grp, u16 vlan_tci)
+{
+	int ret;
+
+	preempt_disable();
+	ret = __vlan_hwaccel_rx(skb, grp, vlan_tci, 0);
+	if (local_softirq_pending())
+		do_softirq();
+	preempt_enable();
+	return ret;
+}
+EXPORT_SYMBOL(vlan_netif_rx);
+
 static void net_tx_action(struct softirq_action *h)
 {
 	struct softnet_data *sd = &__get_cpu_var(softnet_data);
-- 
1.7.9.5


[-- Attachment #3: 0002-vlan-Centralize-handling-of-hardware-acceleration.patch --]
[-- Type: text/x-patch, Size: 10142 bytes --]

>From dbc18ad405cc68c4eabdc64f2afcca5c65d1b96a Mon Sep 17 00:00:00 2001
From: Zhu Yanjun <Yanjun.Zhu@windriver.com>
Date: Thu, 17 Apr 2014 15:58:02 +0800
Subject: [PATCH 2/2] vlan: Centralize handling of hardware acceleration

2.6.x kernels require a similar logic change as commit 4fba4ca4
[vlan: Centralize handling of hardware acceleration] introduces
for newer kernels.

Since there is something wrong with sending/receiving vlan packets
of tun/tap of kernel 2.6.x. In kernel(3.0+), sending/receiving
vlan packets is centralize handling in kernel. But in kernel 2.6.x,
inserting/extraction vlan tag is still based on nic hardware. Thus,
tun/tap nic driver can not support vlan packets. It is necessary
to centralize handling of hardware acceleration and simulate vlan
rx extraction in tun/tap nic driver to make tun/tap support vlan
packets sending/receiving in kernel 2.6.x.

Signed-off-by: Zhu Yanjun <Yanjun.Zhu@windriver.com>
---
 include/linux/if_vlan.h   |    4 +-
 include/linux/netdevice.h |    1 -
 net/8021q/vlan.c          |   47 +++++++++++++++++++
 net/8021q/vlan_core.c     |  110 +++++----------------------------------------
 net/core/dev.c            |   45 +++++++------------
 5 files changed, 74 insertions(+), 133 deletions(-)

diff --git a/include/linux/if_vlan.h b/include/linux/if_vlan.h
index 7ff9af1..5538dda 100644
--- a/include/linux/if_vlan.h
+++ b/include/linux/if_vlan.h
@@ -114,7 +114,7 @@ extern u16 vlan_dev_vlan_id(const struct net_device *dev);
 
 extern int __vlan_hwaccel_rx(struct sk_buff *skb, struct vlan_group *grp,
 			     u16 vlan_tci, int polling);
-extern int vlan_hwaccel_do_receive(struct sk_buff *skb);
+extern bool vlan_hwaccel_do_receive(struct sk_buff **skb);
 extern int vlan_gro_receive(struct napi_struct *napi, struct vlan_group *grp,
 			    unsigned int vlan_tci, struct sk_buff *skb);
 extern int vlan_gro_frags(struct napi_struct *napi, struct vlan_group *grp,
@@ -140,7 +140,7 @@ static inline int __vlan_hwaccel_rx(struct sk_buff *skb, struct vlan_group *grp,
 	return NET_XMIT_SUCCESS;
 }
 
-static inline int vlan_hwaccel_do_receive(struct sk_buff *skb)
+static inline bool vlan_hwaccel_do_receive(struct sk_buff **skb)
 {
 	return 0;
 }
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 04c659b..bdb6b82 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -1490,7 +1490,6 @@ static inline void napi_free_frags(struct napi_struct *napi)
 	napi->skb = NULL;
 }
 
-extern void		netif_nit_deliver(struct sk_buff *skb);
 extern int		dev_valid_name(const char *name);
 extern int		dev_ioctl(struct net *net, unsigned int cmd, void __user *);
 extern int		dev_ethtool(struct net *net, struct ifreq *);
diff --git a/net/8021q/vlan.c b/net/8021q/vlan.c
index a29c5ab..64c081b 100644
--- a/net/8021q/vlan.c
+++ b/net/8021q/vlan.c
@@ -92,6 +92,52 @@ struct net_device *__find_vlan_dev(struct net_device *real_dev, u16 vlan_id)
 	return NULL;
 }
 
+bool vlan_hwaccel_do_receive(struct sk_buff **skbp)
+{
+	struct sk_buff *skb = *skbp;
+	u16 vlan_id = skb->vlan_tci & VLAN_VID_MASK;
+	struct net_device *vlan_dev;
+	struct net_device_stats *stats;
+
+	vlan_dev = __find_vlan_dev(skb->dev, vlan_id);
+	if (!vlan_dev) {
+		if (vlan_id)
+			skb->pkt_type = PACKET_OTHERHOST;
+		return false;
+	}
+
+	skb = *skbp = skb_share_check(skb, GFP_ATOMIC);
+	if (unlikely(!skb))
+		return false;
+
+	skb->dev = vlan_dev;
+	skb->priority = vlan_get_ingress_priority(vlan_dev, skb->vlan_tci);
+	skb->vlan_tci = 0;
+
+	stats = &vlan_dev->stats;
+	stats->rx_packets++;
+	stats->rx_bytes += skb->len;
+
+	switch (skb->pkt_type) {
+	case PACKET_BROADCAST:
+		break;
+	case PACKET_MULTICAST:
+		stats->multicast++;
+		break;
+	case PACKET_OTHERHOST:
+		/* Our lower layer thinks this is not local, let's make sure.
+		 * This allows the VLAN to have a different MAC than the
+		 * underlying device, and still route correctly. */
+		if (!compare_ether_addr(eth_hdr(skb)->h_dest,
+					vlan_dev->dev_addr))
+			skb->pkt_type = PACKET_HOST;
+			break;
+	};
+
+	return true;
+}
+extern bool (*__vlan_do_receive)(struct sk_buff **skbp);
+
 static void vlan_group_free(struct vlan_group *grp)
 {
 	int i;
@@ -744,6 +790,7 @@ static int __init vlan_proto_init(void)
 
 	dev_add_pack(&vlan_packet_type);
 	vlan_ioctl_set(vlan_ioctl_handler);
+	__vlan_do_receive = vlan_hwaccel_do_receive;
 	return 0;
 
 err4:
diff --git a/net/8021q/vlan_core.c b/net/8021q/vlan_core.c
index 7f7de1a..c679535 100644
--- a/net/8021q/vlan_core.c
+++ b/net/8021q/vlan_core.c
@@ -4,64 +4,6 @@
 #include <linux/netpoll.h>
 #include "vlan.h"
 
-/* VLAN rx hw acceleration helper.  This acts like netif_{rx,receive_skb}(). */
-int __vlan_hwaccel_rx(struct sk_buff *skb, struct vlan_group *grp,
-		      u16 vlan_tci, int polling)
-{
-	if (netpoll_rx(skb))
-		return NET_RX_DROP;
-
-	if (skb_bond_should_drop(skb))
-		goto drop;
-
-	skb->vlan_tci = vlan_tci;
-	skb->dev = vlan_group_get_device(grp, vlan_tci & VLAN_VID_MASK);
-
-	if (!skb->dev)
-		goto drop;
-
-	return (polling ? netif_receive_skb(skb) : netif_rx(skb));
-
-drop:
-	dev_kfree_skb_any(skb);
-	return NET_RX_DROP;
-}
-EXPORT_SYMBOL(__vlan_hwaccel_rx);
-
-int vlan_hwaccel_do_receive(struct sk_buff *skb)
-{
-	struct net_device *dev = skb->dev;
-	struct net_device_stats *stats;
-
-	skb->dev = vlan_dev_info(dev)->real_dev;
-	netif_nit_deliver(skb);
-
-	skb->dev = dev;
-	skb->priority = vlan_get_ingress_priority(dev, skb->vlan_tci);
-	skb->vlan_tci = 0;
-
-	stats = &dev->stats;
-	stats->rx_packets++;
-	stats->rx_bytes += skb->len;
-
-	switch (skb->pkt_type) {
-	case PACKET_BROADCAST:
-		break;
-	case PACKET_MULTICAST:
-		stats->multicast++;
-		break;
-	case PACKET_OTHERHOST:
-		/* Our lower layer thinks this is not local, let's make sure.
-		 * This allows the VLAN to have a different MAC than the
-		 * underlying device, and still route correctly. */
-		if (!compare_ether_addr(eth_hdr(skb)->h_dest,
-					dev->dev_addr))
-			skb->pkt_type = PACKET_HOST;
-		break;
-	};
-	return 0;
-}
-
 struct net_device *vlan_dev_real_dev(const struct net_device *dev)
 {
 	return vlan_dev_info(dev)->real_dev;
@@ -74,59 +16,27 @@ u16 vlan_dev_vlan_id(const struct net_device *dev)
 }
 EXPORT_SYMBOL(vlan_dev_vlan_id);
 
-static int vlan_gro_common(struct napi_struct *napi, struct vlan_group *grp,
-			   unsigned int vlan_tci, struct sk_buff *skb)
+/* VLAN rx hw acceleration helper.  This acts like netif_{rx,receive_skb}(). */
+int __vlan_hwaccel_rx(struct sk_buff *skb, struct vlan_group *grp,
+			u16 vlan_tci, int polling)
 {
-	struct sk_buff *p;
-
-	if (skb_bond_should_drop(skb))
-		goto drop;
-
-	skb->vlan_tci = vlan_tci;
-	skb->dev = vlan_group_get_device(grp, vlan_tci & VLAN_VID_MASK);
-
-	if (!skb->dev)
-		goto drop;
-
-	for (p = napi->gro_list; p; p = p->next) {
-		NAPI_GRO_CB(p)->same_flow =
-			p->dev == skb->dev && !compare_ether_header(
-				skb_mac_header(p), skb_gro_mac_header(skb));
-		NAPI_GRO_CB(p)->flush = 0;
-	}
-
-	return dev_gro_receive(napi, skb);
-
-drop:
-	return GRO_DROP;
+	__vlan_hwaccel_put_tag(skb, vlan_tci);
+	return polling ? netif_receive_skb(skb) : netif_rx(skb); 
 }
+EXPORT_SYMBOL(__vlan_hwaccel_rx);
 
 int vlan_gro_receive(struct napi_struct *napi, struct vlan_group *grp,
 		     unsigned int vlan_tci, struct sk_buff *skb)
 {
-	if (netpoll_rx_on(skb))
-		return vlan_hwaccel_receive_skb(skb, grp, vlan_tci);
-
-	skb_gro_reset_offset(skb);
-
-	return napi_skb_finish(vlan_gro_common(napi, grp, vlan_tci, skb), skb);
+	__vlan_hwaccel_put_tag(skb, vlan_tci);
+	return napi_gro_receive(napi, skb);
 }
 EXPORT_SYMBOL(vlan_gro_receive);
 
 int vlan_gro_frags(struct napi_struct *napi, struct vlan_group *grp,
 		   unsigned int vlan_tci)
 {
-	struct sk_buff *skb = napi_frags_skb(napi);
-
-	if (!skb)
-		return NET_RX_DROP;
-
-	if (netpoll_rx_on(skb)) {
-		skb->protocol = eth_type_trans(skb, skb->dev);
-		return vlan_hwaccel_receive_skb(skb, grp, vlan_tci);
-	}
-
-	return napi_frags_finish(napi, skb,
-				 vlan_gro_common(napi, grp, vlan_tci, skb));
+	__vlan_hwaccel_put_tag(napi->skb, vlan_tci);
+	return napi_gro_frags(napi);
 }
 EXPORT_SYMBOL(vlan_gro_frags);
diff --git a/net/core/dev.c b/net/core/dev.c
index a3802ca..c58520a 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -2272,33 +2272,8 @@ out:
 }
 #endif
 
-/*
- * 	netif_nit_deliver - deliver received packets to network taps
- * 	@skb: buffer
- *
- * 	This function is used to deliver incoming packets to network
- * 	taps. It should be used when the normal netif_receive_skb path
- * 	is bypassed, for example because of VLAN acceleration.
- */
-void netif_nit_deliver(struct sk_buff *skb)
-{
-	struct packet_type *ptype;
-
-	if (list_empty(&ptype_all))
-		return;
-
-	skb_reset_network_header(skb);
-	skb_reset_transport_header(skb);
-	skb->mac_len = skb->network_header - skb->mac_header;
-
-	rcu_read_lock();
-	list_for_each_entry_rcu(ptype, &ptype_all, list) {
-		if (!ptype->dev || ptype->dev == skb->dev)
-			deliver_skb(skb, ptype, skb->dev);
-	}
-	rcu_read_unlock();
-}
-
+bool (*__vlan_do_receive)(struct sk_buff **skbp) = NULL;
+EXPORT_SYMBOL(__vlan_do_receive);
 /**
  *	netif_receive_skb - process receive buffer from network
  *	@skb: buffer to process
@@ -2325,9 +2300,6 @@ int netif_receive_skb(struct sk_buff *skb)
 	if (!skb->tstamp.tv64)
 		net_timestamp(skb);
 
-	if (skb->vlan_tci && vlan_hwaccel_do_receive(skb))
-		return NET_RX_SUCCESS;
-
 	/* if we've gotten here through NAPI, check netpoll */
 	if (netpoll_receive_skb(skb))
 		return NET_RX_DROP;
@@ -2354,6 +2326,8 @@ int netif_receive_skb(struct sk_buff *skb)
 
 	rcu_read_lock();
 
+another_round:
+
 #ifdef CONFIG_NET_CLS_ACT
 	if (skb->tc_verd & TC_NCLS) {
 		skb->tc_verd = CLR_TC_NCLS(skb->tc_verd);
@@ -2377,6 +2351,17 @@ int netif_receive_skb(struct sk_buff *skb)
 ncls:
 #endif
 
+	if (vlan_tx_tag_present(skb)) {
+		if (pt_prev) {
+			ret = deliver_skb(skb, pt_prev, orig_dev);
+			pt_prev = NULL;
+		}
+		if (__vlan_do_receive && __vlan_do_receive(&skb)) {
+			goto another_round;
+		} else if (unlikely(!skb))
+			goto out;
+	}
+
 	skb = handle_bridge(skb, &pt_prev, &ret, orig_dev);
 	if (!skb)
 		goto out;
-- 
1.7.9.5


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

* Re: in kernel 2.6.x, tun/tap nic supports vlan packets
  2014-04-17 13:52 ` zhuyj
@ 2014-04-17 14:23   ` Willy Tarreau
  0 siblings, 0 replies; 13+ messages in thread
From: Willy Tarreau @ 2014-04-17 14:23 UTC (permalink / raw)
  To: zhuyj
  Cc: David S. Miller, netdev, joe, julia.lawall, dingtianhong,
	linux-kernel, jasowang, mst, Yang, Zhangle (Eric),
	Wu, Kuaikuai, Tao, Yue

On Thu, Apr 17, 2014 at 09:52:41PM +0800, zhuyj wrote:
> Although the maintainer will not merge these 2 patches, I still fix the 
> mistakes in these 2 patches. Now the latest patches are in attachment. 

Just for the record, I didn't say I "will not" merge them but that I will
not "without an Acked-by from some netdev people who are willing to help
in case of any future regression, which is unlikely but still possible".

That means that if you find someone here to vouch for your patches, I'll
gladly merge them into 2.6.32.x, otherwise not.

> Maybe these patches can help others.
> 
> The latest patches fix mistakes in rx stats.
> 
> Best Regards!
> Zhu Yanjun

Thanks,
Willy


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

* Re: in kernel 2.6.x, tun/tap nic supports vlan packets
  2014-04-17  5:02 ` Willy Tarreau
  2014-04-17  5:50   ` zhuyj
@ 2014-04-19 13:43   ` zhuyj
  2014-04-22 17:53   ` Ben Hutchings
  2 siblings, 0 replies; 13+ messages in thread
From: zhuyj @ 2014-04-19 13:43 UTC (permalink / raw)
  To: Willy Tarreau
  Cc: David S. Miller, netdev, joe, julia.lawall, dingtianhong,
	linux-kernel, jasowang, mst, Yang, Zhangle (Eric),
	Wu, Kuaikuai, Tao, Yue

On 04/17/2014 01:02 PM, Willy Tarreau wrote:
> Hi Zhu,
>
> On Thu, Apr 17, 2014 at 11:35:58AM +0800, zhuyj wrote:
>> Hi, all
>>
>> In kernel 2.6.x, linux depends on nic vlan hardware acceleration to
>> insert/extract
>> vlan tag. In this scene, in kernel 2.6.x
>>
>>                   _____        ________
>>      A           |     | B    |        | C
>>   vlan packets-->| tap |----->|vlan nic|--->
>>                  |_____|      |________|
>>
>> We hope vlan packets pass through tap and vlan nic from A to c.
>> But in kernel 2.6.x, linux kernel can not extract vlan tag. It depends
>> on nic vlan hardware acceleration. It is well known that tap nic has no
>> vlan acceleration. So in the above scene, vlan packets can not be handled by
>> tap nic. These vlan packets will be discarded in B. They can not arrive
>> at C.
> It's not clear to me what you want to achieve. Are you trying to create
> vlan interfaces on top of a tap interface ? Eg: tap1.12, tap1.23 etc ?
>
>> In kernel 3.x, linux can handle vlan packets. It does not depend on nic vlan
>> hardware acceleration. So the above scene can work well in kernel 3.x.
>>
>> To resolve the above in kernel 2.6.x, we simulated vlan hardware
>> acceleration in
>> tun/tap driver. Then followed the logic of commit commit 4fba4ca4
>> [vlan: Centralize handling of hardware acceleration] to modify the vlan
>> packets
>> process in kernel 2.6.x. In the end, the above scene can work well in
>> patched
>> kernel 2.6.x.
>>
>> Please comment on it. Any reply is appreciated.
>>
>> Hi, Willy
>>
>> These 2 patches are for linux2.6.x. These can work well here. Please
>> help to merge
>> linux 2.6.32.x. Thanks a lot.
> Well, 2.6.32.x is in deep freeze mode and it receives only critical fixes
> once in a while. While I can appreciate that the patch above might solve
> the issue you're facing, I'm wondering if there are not any acceptable
> workarounds for such a deep freeze kernel. You patch is not huge, but it
> definitely affects a working driver, and I wouldn't like risking to break
> the tap driver for other users, and I reall don't have the skills to audit
> it completely to ensure this is not the case. And if it breaks, I'll have
> to revert it or seek for some help on netdev.
>
> So I'd say that I'd rather not merge it unless I get an Acked-by from some
> netdev people who are willing to help in case of any future regression,
> which is unlikely but still possible.
>
> Just out of curiosity, what is the motivation for ongoing development on
> top of 2.6.32 ? Are there any important deployments that cannot upgrade
> for any specific reason ? I'm asking because most 2.6.32.x kernels that
> are stuffed into embedded boxes very likely come with their own number
> of in-house patches to add whatever feature is needed in such contexts,
> so I'm wondering why having this patch in mainline would help in your
> situation compared to having it into your own patch set only.
Hi, Willy

I want to submit these 2 patches to this long-term kernel. I have 2 
purposes:

1. I want to share these 2 patches with the ones who need this kind of 
feature. Maybe these 2 patches can help them.
2. When many people make use of these 2 patches, we will find some 
defects. Then we fix them and make this kind of feature better.

Zhu Yanjun
> Thanks,
> Willy
>
>


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

* Re: in kernel 2.6.x, tun/tap nic supports vlan packets
  2014-04-17  5:02 ` Willy Tarreau
  2014-04-17  5:50   ` zhuyj
  2014-04-19 13:43   ` zhuyj
@ 2014-04-22 17:53   ` Ben Hutchings
  2014-04-23  7:48     ` zhuyj
  2 siblings, 1 reply; 13+ messages in thread
From: Ben Hutchings @ 2014-04-22 17:53 UTC (permalink / raw)
  To: Willy Tarreau
  Cc: zhuyj, David S. Miller, netdev, joe, julia.lawall, dingtianhong,
	linux-kernel, jasowang, mst, Yang, Zhangle (Eric),
	Wu, Kuaikuai, Tao, Yue

[-- Attachment #1: Type: text/plain, Size: 2107 bytes --]

On Thu, 2014-04-17 at 07:02 +0200, Willy Tarreau wrote:
> Hi Zhu,
> 
> On Thu, Apr 17, 2014 at 11:35:58AM +0800, zhuyj wrote:
> > Hi, all
> > 
> > In kernel 2.6.x, linux depends on nic vlan hardware acceleration to 
> > insert/extract
> > vlan tag.

This is a gross overstatement.

The problem I know of is that prior to Linux 2.6.37 the RX path behaved
differently for VLAN-tagged packets depending on whether they were
extracted by the driver/hardware.

If you put a bridge (or bond) and VLAN device on top of a single
physical device that doesn't do VLAN tag extraction, the VLAN device
didn't get any packets because the bridge packet handler was called
first.  Whereas, if the driver called the 'VLAN accelerated' RX path,
the VLAN packet handler was called first.  (Linux 2.6.37 actually
standardised on the former behaviour, and 3.2 fixed it to be the
latter.)

I don't know whether that's the problem zhuyj has run into.

[...]
> Well, 2.6.32.x is in deep freeze mode and it receives only critical fixes
> once in a while. While I can appreciate that the patch above might solve
> the issue you're facing, I'm wondering if there are not any acceptable
> workarounds for such a deep freeze kernel. You patch is not huge,

I think it's huge by the standards of 2.6.32.y.

> but it
> definitely affects a working driver, and I wouldn't like risking to break
> the tap driver for other users, and I reall don't have the skills to audit
> it completely to ensure this is not the case. And if it breaks, I'll have
> to revert it or seek for some help on netdev.
> 
> So I'd say that I'd rather not merge it unless I get an Acked-by from some
> netdev people who are willing to help in case of any future regression,
> which is unlikely but still possible.
[...]

For what it's worth, I would recommend against applying this.  I don't
think even Red Hat has backported the VLAN changes, and they have been
quite aggressive about backporting features to RHEL 6.

Ben.

-- 
Ben Hutchings
Beware of programmers who carry screwdrivers. - Leonard Brandwein

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 811 bytes --]

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

* Re: in kernel 2.6.x, tun/tap nic supports vlan packets
  2014-04-22 17:53   ` Ben Hutchings
@ 2014-04-23  7:48     ` zhuyj
  2014-04-23 11:41       ` Ben Hutchings
  0 siblings, 1 reply; 13+ messages in thread
From: zhuyj @ 2014-04-23  7:48 UTC (permalink / raw)
  To: Ben Hutchings, Willy Tarreau
  Cc: David S. Miller, netdev, joe, julia.lawall, dingtianhong,
	linux-kernel, jasowang, mst, Yang, Zhangle (Eric),
	Wu, Kuaikuai, Tao, Yue

On 04/23/2014 01:53 AM, Ben Hutchings wrote:
> On Thu, 2014-04-17 at 07:02 +0200, Willy Tarreau wrote:
>> Hi Zhu,
>>
>> On Thu, Apr 17, 2014 at 11:35:58AM +0800, zhuyj wrote:
>>> Hi, all
>>>
>>> In kernel 2.6.x, linux depends on nic vlan hardware acceleration to
>>> insert/extract
>>> vlan tag.
Hi, Ben

Thanks for your reply.
> This is a gross overstatement.
>
> The problem I know of is that prior to Linux 2.6.37 the RX path behaved
> differently for VLAN-tagged packets depending on whether they were
> extracted by the driver/hardware.
Yes. You are right. So I backported 
0002-vlan-Centralize-handling-of-hardware-acceleration.patch to fix this 
problem.
>
> If you put a bridge (or bond) and VLAN device on top of a single
> physical device that doesn't do VLAN tag extraction, the VLAN device
> didn't get any packets because the bridge packet handler was called
> first.  Whereas, if the driver called the 'VLAN accelerated' RX path,
> the VLAN packet handler was called first.  (Linux 2.6.37 actually
> standardised on the former behaviour, and 3.2 fixed it to be the
> latter.)
Yes. So I made a patch 
"0001-tun-tap-add-the-feature-of-vlan-rx-extraction.patch" to make tap 
driver extract vlan tag.
>
> I don't know whether that's the problem zhuyj has run into.
>
> [...]
>> Well, 2.6.32.x is in deep freeze mode and it receives only critical fixes
>> once in a while. While I can appreciate that the patch above might solve
>> the issue you're facing, I'm wondering if there are not any acceptable
>> workarounds for such a deep freeze kernel. You patch is not huge,
> I think it's huge by the standards of 2.6.32.y.
>
>> but it
>> definitely affects a working driver, and I wouldn't like risking to break
>> the tap driver for other users, and I reall don't have the skills to audit
>> it completely to ensure this is not the case. And if it breaks, I'll have
>> to revert it or seek for some help on netdev.
>>
>> So I'd say that I'd rather not merge it unless I get an Acked-by from some
>> netdev people who are willing to help in case of any future regression,
>> which is unlikely but still possible.
> [...]
>
> For what it's worth, I would recommend against applying this.  I don't
> think even Red Hat has backported the VLAN changes, and they have been
> quite aggressive about backporting features to RHEL 6.
If we do not merge these patches, maybe RHEL 6 can not make tap driver 
support vlan well.

Best Regards!
Zhu Yanjun
>
> Ben.
>


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

* Re: in kernel 2.6.x, tun/tap nic supports vlan packets
  2014-04-23  7:48     ` zhuyj
@ 2014-04-23 11:41       ` Ben Hutchings
  2014-04-24  2:10         ` zhuyj
  0 siblings, 1 reply; 13+ messages in thread
From: Ben Hutchings @ 2014-04-23 11:41 UTC (permalink / raw)
  To: zhuyj
  Cc: Willy Tarreau, David S. Miller, netdev, joe, julia.lawall,
	dingtianhong, linux-kernel, jasowang, mst, Yang, Zhangle (Eric),
	Wu, Kuaikuai, Tao, Yue

[-- Attachment #1: Type: text/plain, Size: 580 bytes --]

On Wed, 2014-04-23 at 15:48 +0800, zhuyj wrote:
> On 04/23/2014 01:53 AM, Ben Hutchings wrote:
[...]
> > For what it's worth, I would recommend against applying this.  I don't
> > think even Red Hat has backported the VLAN changes, and they have been
> > quite aggressive about backporting features to RHEL 6.
> If we do not merge these patches, maybe RHEL 6 can not make tap driver 
> support vlan well.

RHEL 6 isn't based on 2.6.32.y, they do all their own backporting.

Ben.

-- 
Ben Hutchings
Beware of programmers who carry screwdrivers. - Leonard Brandwein

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 811 bytes --]

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

* Re: in kernel 2.6.x, tun/tap nic supports vlan packets
  2014-04-23 11:41       ` Ben Hutchings
@ 2014-04-24  2:10         ` zhuyj
  2014-04-24  5:24           ` Willy Tarreau
  0 siblings, 1 reply; 13+ messages in thread
From: zhuyj @ 2014-04-24  2:10 UTC (permalink / raw)
  To: Ben Hutchings
  Cc: Willy Tarreau, David S. Miller, netdev, joe, julia.lawall,
	dingtianhong, linux-kernel, jasowang, mst, Yang, Zhangle (Eric),
	Wu, Kuaikuai, Tao, Yue, zhuyj

On 04/23/2014 07:41 PM, Ben Hutchings wrote:
> On Wed, 2014-04-23 at 15:48 +0800, zhuyj wrote:
>> On 04/23/2014 01:53 AM, Ben Hutchings wrote:
> [...]
>>> For what it's worth, I would recommend against applying this.  I don't
>>> think even Red Hat has backported the VLAN changes, and they have been
>>> quite aggressive about backporting features to RHEL 6.
>> If we do not merge these patches, maybe RHEL 6 can not make tap driver
>> support vlan well.
> RHEL 6 isn't based on 2.6.32.y, they do all their own backporting.
Hi, Ben

It is well known that extraction vlan tag is not implemented in kernel 
2.6.32.y.  Kernel 2.6.32.y depends on nic hardware to extract vlan tag.
So if the patches are not applied, tap driver can not support vlan well.

Best Regards!
Zhu Yanjun
> Ben.
>


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

* Re: in kernel 2.6.x, tun/tap nic supports vlan packets
  2014-04-24  2:10         ` zhuyj
@ 2014-04-24  5:24           ` Willy Tarreau
  2014-04-25  8:09             ` zhuyj
  0 siblings, 1 reply; 13+ messages in thread
From: Willy Tarreau @ 2014-04-24  5:24 UTC (permalink / raw)
  To: zhuyj
  Cc: Ben Hutchings, David S. Miller, netdev, joe, julia.lawall,
	dingtianhong, linux-kernel, jasowang, mst, Yang, Zhangle (Eric),
	Wu, Kuaikuai, Tao, Yue

On Thu, Apr 24, 2014 at 10:10:08AM +0800, zhuyj wrote:
> On 04/23/2014 07:41 PM, Ben Hutchings wrote:
> >On Wed, 2014-04-23 at 15:48 +0800, zhuyj wrote:
> >>On 04/23/2014 01:53 AM, Ben Hutchings wrote:
> >[...]
> >>>For what it's worth, I would recommend against applying this.  I don't
> >>>think even Red Hat has backported the VLAN changes, and they have been
> >>>quite aggressive about backporting features to RHEL 6.
> >>If we do not merge these patches, maybe RHEL 6 can not make tap driver
> >>support vlan well.
> >RHEL 6 isn't based on 2.6.32.y, they do all their own backporting.
> Hi, Ben
> 
> It is well known that extraction vlan tag is not implemented in kernel 
> 2.6.32.y.  Kernel 2.6.32.y depends on nic hardware to extract vlan tag.
> So if the patches are not applied, tap driver can not support vlan well.

What Ben is saying is that RHEL doesn't use 2.6.32.y, but did their own
fork of 2.6.32 so even if we merged your patch, they wouldn't pick it
from this tree anyway. However they could possibly take your patch if
some customers requested the feature even if it's not in 2.6.32.y.

Clearly, the fact that nobody complained about this in 4.5 years of
2.6.32 means that there's no particular reason any user would suddenly
miss it now. 2.6.32.y is mostly used to update existing deployments but
rarely for new deployments. That's why the usefulness of your backport
in this kernel for its users is likely limited, and at the same time
the risk of causing a regression is far from being null for existing
users (eg: if some worked around the issue a different way, their
workaround would likely not work anymore).

Best regards,
Willy


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

* Re: in kernel 2.6.x, tun/tap nic supports vlan packets
  2014-04-24  5:24           ` Willy Tarreau
@ 2014-04-25  8:09             ` zhuyj
  0 siblings, 0 replies; 13+ messages in thread
From: zhuyj @ 2014-04-25  8:09 UTC (permalink / raw)
  To: Willy Tarreau
  Cc: Ben Hutchings, David S. Miller, netdev, joe, julia.lawall,
	dingtianhong, linux-kernel, jasowang, mst, Yang, Zhangle (Eric),
	Wu, Kuaikuai, Tao, Yue

On 04/24/2014 01:24 PM, Willy Tarreau wrote:
> On Thu, Apr 24, 2014 at 10:10:08AM +0800, zhuyj wrote:
>> On 04/23/2014 07:41 PM, Ben Hutchings wrote:
>>> On Wed, 2014-04-23 at 15:48 +0800, zhuyj wrote:
>>>> On 04/23/2014 01:53 AM, Ben Hutchings wrote:
>>> [...]
>>>>> For what it's worth, I would recommend against applying this.  I don't
>>>>> think even Red Hat has backported the VLAN changes, and they have been
>>>>> quite aggressive about backporting features to RHEL 6.
>>>> If we do not merge these patches, maybe RHEL 6 can not make tap driver
>>>> support vlan well.
>>> RHEL 6 isn't based on 2.6.32.y, they do all their own backporting.
>> Hi, Ben
>>
>> It is well known that extraction vlan tag is not implemented in kernel
>> 2.6.32.y.  Kernel 2.6.32.y depends on nic hardware to extract vlan tag.
>> So if the patches are not applied, tap driver can not support vlan well.
> What Ben is saying is that RHEL doesn't use 2.6.32.y, but did their own
> fork of 2.6.32 so even if we merged your patch, they wouldn't pick it
> from this tree anyway. However they could possibly take your patch if
> some customers requested the feature even if it's not in 2.6.32.y.
OK. as your wish.

Best Regards!
Zhu Yanjun
>
> Clearly, the fact that nobody complained about this in 4.5 years of
> 2.6.32 means that there's no particular reason any user would suddenly
> miss it now. 2.6.32.y is mostly used to update existing deployments but
> rarely for new deployments. That's why the usefulness of your backport
> in this kernel for its users is likely limited, and at the same time
> the risk of causing a regression is far from being null for existing
> users (eg: if some worked around the issue a different way, their
> workaround would likely not work anymore).
>
> Best regards,
> Willy
>
>


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

end of thread, other threads:[~2014-04-25  8:09 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-04-17  3:35 in kernel 2.6.x, tun/tap nic supports vlan packets zhuyj
2014-04-17  5:02 ` Willy Tarreau
2014-04-17  5:50   ` zhuyj
2014-04-19 13:43   ` zhuyj
2014-04-22 17:53   ` Ben Hutchings
2014-04-23  7:48     ` zhuyj
2014-04-23 11:41       ` Ben Hutchings
2014-04-24  2:10         ` zhuyj
2014-04-24  5:24           ` Willy Tarreau
2014-04-25  8:09             ` zhuyj
2014-04-17  6:27 ` zhuyj
2014-04-17 13:52 ` zhuyj
2014-04-17 14:23   ` Willy Tarreau

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