aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/bonding
diff options
context:
space:
mode:
authorJohn W. Linville <linville@tuxdriver.com>2005-09-28 17:50:53 -0400
committerJeff Garzik <jgarzik@pobox.com>2005-10-04 07:57:38 -0400
commit075897ce3b1027fccb98f36dd1f18c07f5c374ef (patch)
treea795da3ac5c888f16b96082ddbd3d01c8c05493d /drivers/net/bonding
parent6c1792f4e8cf2ca03a8dd5ec4b162b9219e9268a (diff)
[PATCH] bonding: replicate IGMP traffic in activebackup mode
Replicate IGMP frames across all slaves in activebackup mode. This ensures fail-over is rapid for multicast traffic as well. Otherwise, multicast traffic will be lost until the next IGMP membership report poll timeout. This is conceptually similar to the treatment of IGMP traffic in bond_alb_xmit. In that case, IGMP traffic transmitted on any slave is re-routed to the active slave in order to ensure that multicast traffic continues to be directed to the active receiver. Signed-off-by: John W. Linville <linville@tuxdriver.com> Signed-off-by: Jeff Garzik <jgarzik@pobox.com>
Diffstat (limited to 'drivers/net/bonding')
-rw-r--r--drivers/net/bonding/bond_main.c53
1 files changed, 51 insertions, 2 deletions
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index fd62e43a3510..2c9e63a14596 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -4240,6 +4240,39 @@ out:
4240 return 0; 4240 return 0;
4241} 4241}
4242 4242
4243static void bond_activebackup_xmit_copy(struct sk_buff *skb,
4244 struct bonding *bond,
4245 struct slave *slave)
4246{
4247 struct sk_buff *skb2 = skb_copy(skb, GFP_ATOMIC);
4248 struct ethhdr *eth_data;
4249 u8 *hwaddr;
4250 int res;
4251
4252 if (!skb2) {
4253 printk(KERN_ERR DRV_NAME ": Error: "
4254 "bond_activebackup_xmit_copy(): skb_copy() failed\n");
4255 return;
4256 }
4257
4258 skb2->mac.raw = (unsigned char *)skb2->data;
4259 eth_data = eth_hdr(skb2);
4260
4261 /* Pick an appropriate source MAC address */
4262 hwaddr = slave->perm_hwaddr;
4263 if (!memcmp(eth_data->h_source, hwaddr, ETH_ALEN))
4264 hwaddr = bond->curr_active_slave->perm_hwaddr;
4265
4266 /* Set source MAC address appropriately */
4267 memcpy(eth_data->h_source, hwaddr, ETH_ALEN);
4268
4269 res = bond_dev_queue_xmit(bond, skb2, slave->dev);
4270 if (res)
4271 dev_kfree_skb(skb2);
4272
4273 return;
4274}
4275
4243/* 4276/*
4244 * in active-backup mode, we know that bond->curr_active_slave is always valid if 4277 * in active-backup mode, we know that bond->curr_active_slave is always valid if
4245 * the bond has a usable interface. 4278 * the bond has a usable interface.
@@ -4256,10 +4289,26 @@ static int bond_xmit_activebackup(struct sk_buff *skb, struct net_device *bond_d
4256 goto out; 4289 goto out;
4257 } 4290 }
4258 4291
4259 if (bond->curr_active_slave) { /* one usable interface */ 4292 if (!bond->curr_active_slave)
4260 res = bond_dev_queue_xmit(bond, skb, bond->curr_active_slave->dev); 4293 goto out;
4294
4295 /* Xmit IGMP frames on all slaves to ensure rapid fail-over
4296 for multicast traffic on snooping switches */
4297 if (skb->protocol == __constant_htons(ETH_P_IP) &&
4298 skb->nh.iph->protocol == IPPROTO_IGMP) {
4299 struct slave *slave, *active_slave;
4300 int i;
4301
4302 active_slave = bond->curr_active_slave;
4303 bond_for_each_slave_from_to(bond, slave, i, active_slave->next,
4304 active_slave->prev)
4305 if (IS_UP(slave->dev) &&
4306 (slave->link == BOND_LINK_UP))
4307 bond_activebackup_xmit_copy(skb, bond, slave);
4261 } 4308 }
4262 4309
4310 res = bond_dev_queue_xmit(bond, skb, bond->curr_active_slave->dev);
4311
4263out: 4312out:
4264 if (res) { 4313 if (res) {
4265 /* no suitable interface, frame not sent */ 4314 /* no suitable interface, frame not sent */