in kernel 2.6.x, tun/tap nic supports vlan packets
Subsystems (3)
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
Quoted 1 line
From
66db0748fc0f932496100789eb319ca5884c0694Mon Sep 17 00:00:00 2001
From: Zhu Yanjun <[email protected]>
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.
--- drivers/net/tun.c | 118 ++++++++++++++++++++++++++++++++++++++++++++- include/linux/netdevice.h | 1 + net/core/dev.c | 13 +++++ 3 files changed, 131 insertions(+), 1 deletion(-)
drivers/net/tun.c +117 -1
@@ -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;
include/linux/netdevice.h +1 -0
@@ -1467,6 +1467,7 @@ extern void dev_kfree_skb_any(struct sk_buff *skb);#define HAVE_NETIF_RX 1extern 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 1extern int netif_receive_skb (struct sk_buff *skb);extern void napi_gro_flush (struct napi_struct *napi);
net/core/dev.c +13 -0
@@ -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);
Signature · 1 line
1.7.9.5
Quoted 1 line
From
86fff983b7f36750301aab537dfd4e5744d929e7Mon Sep 17 00:00:00 2001
From: Zhu Yanjun <[email protected]>
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.
--- 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(-)
include/linux/if_vlan.h +2 -2
@@ -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 ; }
include/linux/netdevice.h +0 -1
@@ -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 *);
net/8021q/vlan.c +49 -0
61 lines not on this page · raw message
net/8021q/vlan_core.c +10 -100
133 lines not on this page · raw message
net/core/dev.c +15 -27
60 lines not on this page · raw message
Signature · 1 line
1.7.9.5
Hi Zhu,
Quoted 11 lines · zhuyj
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 | | Cvlan packets-->| tap |----->|vlan nic|---> |_____| |________|
Quoted 6 lines
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 ?
Quoted 12 lines
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 commit4fba4ca4[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.
Quoted 7 lines
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
Quoted 14 lines · Willy Tarreau
Hi Zhu,
Quoted 11 lines · zhuyj
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 | | Cvlan packets-->| tap |----->|vlan nic|---> |_____| |________|
Quoted 8 lines
Quoted 6 lines
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
Quoted 45 lines
Quoted 13 lines
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 commit4fba4ca4[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.Quoted 7 lines
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
Quoted 55 lines · Willy Tarreau
Hi Zhu,
Quoted 11 lines · zhuyj
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 | | Cvlan packets-->| tap |----->|vlan nic|---> |_____| |________|Quoted 6 lines
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 ?
Quoted 12 lines
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 commit4fba4ca4[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.Quoted 7 lines
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.
Quoted 7 lines
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
Quoted 4 lines
Thanks,
Willy
Quoted 8 lines · Willy Tarreau
Hi Zhu,
Quoted 5 lines · zhuyj
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.
[...]
Quoted 4 lines
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.
Quoted 9 lines
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.
Signature · 2 lines
Ben Hutchings Beware of programmers who carry screwdrivers. - Leonard Brandwein
Quoted 9 lines · Ben Hutchings
Quoted 8 lines · Willy Tarreau
Hi Zhu,
Quoted 5 lines · zhuyj
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.
Quoted 5 lines
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.
Quoted 8 lines
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.
Quoted 16 lines
I don't know whether that's the problem zhuyj has run into.
[...]
Quoted 4 lines
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.
Quoted 6 lines
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.
Quoted 8 lines
Quoted 3 lines
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
Quoted 3 lines
Ben.
Quoted 1 line · zhuyj
On 04/23/2014 01:53 AM, Ben Hutchings wrote:
[...]
Quoted 5 lines
Quoted 3 lines
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.
Signature · 2 lines
Ben Hutchings Beware of programmers who carry screwdrivers. - Leonard Brandwein
Quoted 9 lines · Ben Hutchings
Quoted 1 line · zhuyj
On 04/23/2014 01:53 AM, Ben Hutchings wrote:
[...]
Quoted 5 lines
Quoted 3 lines
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
Quoted 2 lines
Ben.
Quoted 7 lines · zhuyj
Quoted 6 lines · Ben Hutchings
Quoted 1 line · zhuyj
On 04/23/2014 01:53 AM, Ben Hutchings wrote:
[...]
Quoted 3 lines
Quoted 3 lines
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.
Quoted 8 lines
Quoted 3 lines
Quoted 2 lines
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
Quoted 13 lines · Willy Tarreau
Quoted 12 lines · zhuyj
Quoted 9 lines · Ben Hutchings
Quoted 1 line · zhuyj
On 04/23/2014 01:53 AM, Ben Hutchings wrote:
[...]
Quoted 5 lines
Quoted 3 lines
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
Quoted 7 lines
Quoted 3 lines
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
Quoted 14 lines
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
Hi, Jaso
Would you like to code review these 2 patches?
Thanks a lot.
Zhu Yanjun
Quoted 35 lines · zhuyj
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 | | Cvlan 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
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
Quoted 29 lines · zhuyj
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 | | Cvlan 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
Quoted 8 lines
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 YanjunFrom
66db0748fc0f932496100789eb319ca5884c0694Mon 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.
--- drivers/net/tun.c | 118 ++++++++++++++++++++++++++++++++++++++++++++- include/linux/netdevice.h | 1 + net/core/dev.c | 13 +++++ 3 files changed, 131 insertions(+), 1 deletion(-)
drivers/net/tun.c +117 -1
@@ -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;
include/linux/netdevice.h +1 -0
@@ -1467,6 +1467,7 @@ extern void dev_kfree_skb_any(struct sk_buff *skb);#define HAVE_NETIF_RX 1extern 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 1extern int netif_receive_skb (struct sk_buff *skb);extern void napi_gro_flush (struct napi_struct *napi);
net/core/dev.c +13 -0
@@ -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);
Signature · 1 line
1.7.9.5
Quoted 1 line
From
dbc18ad405cc68c4eabdc64f2afcca5c65d1b96aMon Sep 17 00:00:00 2001
From: Zhu Yanjun <[email protected]>
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.
--- 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(-)
include/linux/if_vlan.h +2 -2
@@ -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 ; }
include/linux/netdevice.h +0 -1
@@ -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 *);
net/8021q/vlan.c +47 -0
59 lines not on this page · raw message
net/8021q/vlan_core.c +10 -100
133 lines not on this page · raw message
net/core/dev.c +15 -30
69 lines not on this page · raw message
Signature · 1 line
1.7.9.5
Quoted 2 lines · zhuyj
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.
Quoted 6 lines
Maybe these patches can help others.
The latest patches fix mistakes in rx stats.
Best Regards!
Zhu Yanjun
Thanks,
Willy