aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorJay Vosburgh <fubar@us.ibm.com>2008-11-04 20:51:15 -0500
committerJeff Garzik <jgarzik@redhat.com>2008-11-06 00:49:40 -0500
commit6146b1a4da98377e4abddc91ba5856bef8f23f1e (patch)
tree1082fdb4b0a92d85ec60666f2c8d29ab3fef9ebe /drivers/net
parent305d552accae6afb859c493ebc7d98ca3371dae2 (diff)
bonding: Fix ALB mode to balance traffic on VLANs
The current ALB function that processes incoming ARPs does not handle traffic for VLANs configured above bonding. This causes traffic on those VLANs to all be assigned the same slave. This patch corrects that misbehavior by locating the bonding interface nested below the VLAN interface. Bug reported by Sven Anders <anders@anduras.de>, who also tested an earlier version of this patch and confirmed that it resolved the problem. Signed-off-by: Jay Vosburgh <fubar@us.ibm.com> Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/bonding/bond_alb.c13
1 files changed, 10 insertions, 3 deletions
diff --git a/drivers/net/bonding/bond_alb.c b/drivers/net/bonding/bond_alb.c
index 87437c788476..e170fa2fa1a1 100644
--- a/drivers/net/bonding/bond_alb.c
+++ b/drivers/net/bonding/bond_alb.c
@@ -346,14 +346,18 @@ static void rlb_update_entry_from_arp(struct bonding *bond, struct arp_pkt *arp)
346 346
347static int rlb_arp_recv(struct sk_buff *skb, struct net_device *bond_dev, struct packet_type *ptype, struct net_device *orig_dev) 347static int rlb_arp_recv(struct sk_buff *skb, struct net_device *bond_dev, struct packet_type *ptype, struct net_device *orig_dev)
348{ 348{
349 struct bonding *bond = bond_dev->priv; 349 struct bonding *bond;
350 struct arp_pkt *arp = (struct arp_pkt *)skb->data; 350 struct arp_pkt *arp = (struct arp_pkt *)skb->data;
351 int res = NET_RX_DROP; 351 int res = NET_RX_DROP;
352 352
353 if (dev_net(bond_dev) != &init_net) 353 if (dev_net(bond_dev) != &init_net)
354 goto out; 354 goto out;
355 355
356 if (!(bond_dev->flags & IFF_MASTER)) 356 while (bond_dev->priv_flags & IFF_802_1Q_VLAN)
357 bond_dev = vlan_dev_real_dev(bond_dev);
358
359 if (!(bond_dev->priv_flags & IFF_BONDING) ||
360 !(bond_dev->flags & IFF_MASTER))
357 goto out; 361 goto out;
358 362
359 if (!arp) { 363 if (!arp) {
@@ -368,6 +372,9 @@ static int rlb_arp_recv(struct sk_buff *skb, struct net_device *bond_dev, struct
368 372
369 if (arp->op_code == htons(ARPOP_REPLY)) { 373 if (arp->op_code == htons(ARPOP_REPLY)) {
370 /* update rx hash table for this ARP */ 374 /* update rx hash table for this ARP */
375 printk("rar: update orig %s bond_dev %s\n", orig_dev->name,
376 bond_dev->name);
377 bond = bond_dev->priv;
371 rlb_update_entry_from_arp(bond, arp); 378 rlb_update_entry_from_arp(bond, arp);
372 dprintk("Server received an ARP Reply from client\n"); 379 dprintk("Server received an ARP Reply from client\n");
373 } 380 }
@@ -818,7 +825,7 @@ static int rlb_initialize(struct bonding *bond)
818 825
819 /*initialize packet type*/ 826 /*initialize packet type*/
820 pk_type->type = __constant_htons(ETH_P_ARP); 827 pk_type->type = __constant_htons(ETH_P_ARP);
821 pk_type->dev = bond->dev; 828 pk_type->dev = NULL;
822 pk_type->func = rlb_arp_recv; 829 pk_type->func = rlb_arp_recv;
823 830
824 /* register to receive ARPs */ 831 /* register to receive ARPs */