Skip to content

Commit

Permalink
[PATCH] bonding: replicate IGMP traffic in activebackup mode
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
John W. Linville authored and Jeff Garzik committed Oct 4, 2005
1 parent 6c1792f commit 075897c
Showing 1 changed file with 51 additions and 2 deletions.
53 changes: 51 additions & 2 deletions drivers/net/bonding/bond_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -4240,6 +4240,39 @@ static int bond_xmit_roundrobin(struct sk_buff *skb, struct net_device *bond_dev
return 0;
}

static void bond_activebackup_xmit_copy(struct sk_buff *skb,
struct bonding *bond,
struct slave *slave)
{
struct sk_buff *skb2 = skb_copy(skb, GFP_ATOMIC);
struct ethhdr *eth_data;
u8 *hwaddr;
int res;

if (!skb2) {
printk(KERN_ERR DRV_NAME ": Error: "
"bond_activebackup_xmit_copy(): skb_copy() failed\n");
return;
}

skb2->mac.raw = (unsigned char *)skb2->data;
eth_data = eth_hdr(skb2);

/* Pick an appropriate source MAC address */
hwaddr = slave->perm_hwaddr;
if (!memcmp(eth_data->h_source, hwaddr, ETH_ALEN))
hwaddr = bond->curr_active_slave->perm_hwaddr;

/* Set source MAC address appropriately */
memcpy(eth_data->h_source, hwaddr, ETH_ALEN);

res = bond_dev_queue_xmit(bond, skb2, slave->dev);
if (res)
dev_kfree_skb(skb2);

return;
}

/*
* in active-backup mode, we know that bond->curr_active_slave is always valid if
* the bond has a usable interface.
Expand All @@ -4256,10 +4289,26 @@ static int bond_xmit_activebackup(struct sk_buff *skb, struct net_device *bond_d
goto out;
}

if (bond->curr_active_slave) { /* one usable interface */
res = bond_dev_queue_xmit(bond, skb, bond->curr_active_slave->dev);
if (!bond->curr_active_slave)
goto out;

/* Xmit IGMP frames on all slaves to ensure rapid fail-over
for multicast traffic on snooping switches */
if (skb->protocol == __constant_htons(ETH_P_IP) &&
skb->nh.iph->protocol == IPPROTO_IGMP) {
struct slave *slave, *active_slave;
int i;

active_slave = bond->curr_active_slave;
bond_for_each_slave_from_to(bond, slave, i, active_slave->next,
active_slave->prev)
if (IS_UP(slave->dev) &&
(slave->link == BOND_LINK_UP))
bond_activebackup_xmit_copy(skb, bond, slave);
}

res = bond_dev_queue_xmit(bond, skb, bond->curr_active_slave->dev);

out:
if (res) {
/* no suitable interface, frame not sent */
Expand Down

0 comments on commit 075897c

Please sign in to comment.