aboutsummaryrefslogtreecommitdiff
path: root/drivers/net
diff options
context:
space:
mode:
authorBen Hutchings <bhutchings@solarflare.com>2011-02-07 19:20:55 +0000
committerAK <andi@firstfloor.org>2011-03-31 11:58:04 -0700
commited887b2eed606d4267e950161d40b9d36154ff30 (patch)
tree7616a7725e493fc44e9cac55572c8da57f953b6c /drivers/net
parent515884e98dc4f1c99387000d420394c3bc47c0d7 (diff)
bonding/vlan: Avoid mangled NAs on slaves without VLAN tag insertion
This is related to commit f88a4a9b65a6f3422b81be995535d0e69df11bb8 upstream, but the bug cannot be properly fixed without the other changes to VLAN tagging in 2.6.37. bond_na_send() attempts to insert a VLAN tag in between building and sending packets of the respective formats. If the slave does not implement hardware VLAN tag insertion then vlan_put_tag() will mangle the network-layer header because the Ethernet header is not present at this point (unlike in bond_arp_send()). Signed-off-by: Ben Hutchings <bhutchings@solarflare.com> Acked-by: David S. Miller <davem@davemloft.net> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> Signed-off-by: Andi Kleen <ak@linux.intel.com>
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/bonding/bond_ipv6.c9
1 files changed, 8 insertions, 1 deletions
diff --git a/drivers/net/bonding/bond_ipv6.c b/drivers/net/bonding/bond_ipv6.c
index 969ffed86b9..07fa65f5d58 100644
--- a/drivers/net/bonding/bond_ipv6.c
+++ b/drivers/net/bonding/bond_ipv6.c
@@ -70,6 +70,13 @@ static void bond_na_send(struct net_device *slave_dev,
};
struct sk_buff *skb;
+ /* The Ethernet header is built in ndisc_send_skb(), not
+ * ndisc_build_skb(), so we cannot insert a VLAN tag. Only an
+ * out-of-line tag inserted by the hardware will work.
+ */
+ if (vlan_id && !(slave_dev->features & NETIF_F_HW_VLAN_TX))
+ return;
+
icmp6h.icmp6_router = router;
icmp6h.icmp6_solicited = 0;
icmp6h.icmp6_override = 1;
@@ -88,7 +95,7 @@ static void bond_na_send(struct net_device *slave_dev,
}
if (vlan_id) {
- skb = vlan_put_tag(skb, vlan_id);
+ skb = __vlan_hwaccel_put_tag(skb, vlan_id);
if (!skb) {
pr_err("failed to insert VLAN tag\n");
return;