From: t_jeang Date: Tue, 6 Jan 2009 12:06:05 +0000 (+0000) Subject: imported patch bonding-vlan-fixes.patch X-Git-Tag: debug-dump-skb-info-when-invalid X-Git-Url: http://xenbits.xensource.com/gitweb?a=commitdiff_plain;h=802968d8a7bade8bbfd6ba3c13479733b7e10bb4;p=xenclient%2Fkernel.git imported patch bonding-vlan-fixes.patch --- diff --git a/net/core/dev.c b/net/core/dev.c index 4110f7cd..3034276c 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -88,6 +88,7 @@ #include #include #include +#include #include #include #include @@ -1699,6 +1700,8 @@ int netif_rx_ni(struct sk_buff *skb) EXPORT_SYMBOL(netif_rx_ni); +#include <../drivers/net/bonding/bonding.h> + static inline struct net_device *skb_bond(struct sk_buff *skb) { struct net_device *dev = skb->dev; @@ -1709,6 +1712,42 @@ static inline struct net_device *skb_bond(struct sk_buff *skb) return NULL; } skb->dev = dev->master; + + /* The bonding driver claims to support rx vlan h/w acceleration. + * It actually just assumes the slave supports it and offloads the + * the responsibility for the acceleration to the slave. + * If the slave does not support rx vlan h/w acceleration + * then the tagged frames will end up here. + * When this happens we need to emulate the rx vlan h/w acceleration + * feature that is missing in the slave. + */ + if (!(dev->features & NETIF_F_HW_VLAN_RX) && + (dev->master->features & NETIF_F_HW_VLAN_RX)) { + + struct bonding *bond = dev->master->priv; + struct vlan_group *grp = bond->vlgrp; + struct ethhdr *hdr = eth_hdr(skb); + + if (hdr->h_proto == htons(ETH_P_8021Q) && grp && + skb->len >= VLAN_ETH_HLEN) { + struct vlan_ethhdr *vhdr = vlan_eth_hdr(skb); + u16 vtag = ntohs(vhdr->h_vlan_TCI); + + /* Reset skb->data to the start of the frame */ + __skb_push(skb, skb->data - skb->mac.raw); + + /* Ditch the 4 byte vlan shim */ + memmove(skb->mac.raw + VLAN_HLEN, skb->mac.raw, ETH_ALEN * 2); + __skb_pull(skb, VLAN_HLEN); + + /* Update the skb details */ + skb->protocol = eth_type_trans(skb, skb->dev); + + /* Pass up the stack as if it came from bond0 */ + vlan_hwaccel_rx(skb, grp, vtag); + return NULL; + } + } } return dev;