|
@@ -60,6 +60,7 @@
|
|
|
#include <linux/errno.h>
|
|
|
#include <linux/netdevice.h>
|
|
|
#include <linux/inetdevice.h>
|
|
|
+#include <linux/igmp.h>
|
|
|
#include <linux/etherdevice.h>
|
|
|
#include <linux/skbuff.h>
|
|
|
#include <net/sock.h>
|
|
@@ -861,6 +862,28 @@ static void bond_mc_delete(struct bonding *bond, void *addr, int alen)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+
|
|
|
+/*
|
|
|
+ * Retrieve the list of registered multicast addresses for the bonding
|
|
|
+ * device and retransmit an IGMP JOIN request to the current active
|
|
|
+ * slave.
|
|
|
+ */
|
|
|
+static void bond_resend_igmp_join_requests(struct bonding *bond)
|
|
|
+{
|
|
|
+ struct in_device *in_dev;
|
|
|
+ struct ip_mc_list *im;
|
|
|
+
|
|
|
+ rcu_read_lock();
|
|
|
+ in_dev = __in_dev_get_rcu(bond->dev);
|
|
|
+ if (in_dev) {
|
|
|
+ for (im = in_dev->mc_list; im; im = im->next) {
|
|
|
+ ip_mc_rejoin_group(im);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ rcu_read_unlock();
|
|
|
+}
|
|
|
+
|
|
|
/*
|
|
|
* Totally destroys the mc_list in bond
|
|
|
*/
|
|
@@ -874,6 +897,7 @@ static void bond_mc_list_destroy(struct bonding *bond)
|
|
|
kfree(dmi);
|
|
|
dmi = bond->mc_list;
|
|
|
}
|
|
|
+ bond->mc_list = NULL;
|
|
|
}
|
|
|
|
|
|
/*
|
|
@@ -967,6 +991,7 @@ static void bond_mc_swap(struct bonding *bond, struct slave *new_active, struct
|
|
|
for (dmi = bond->dev->mc_list; dmi; dmi = dmi->next) {
|
|
|
dev_mc_add(new_active->dev, dmi->dmi_addr, dmi->dmi_addrlen, 0);
|
|
|
}
|
|
|
+ bond_resend_igmp_join_requests(bond);
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -4017,42 +4042,6 @@ out:
|
|
|
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
|
|
|
- * -- use slave's perm MAC addr, unless used by bond
|
|
|
- * -- otherwise, borrow active slave's perm MAC addr
|
|
|
- * since that will not be used
|
|
|
- */
|
|
|
- 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
|
|
@@ -4073,21 +4062,6 @@ static int bond_xmit_activebackup(struct sk_buff *skb, struct net_device *bond_d
|
|
|
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:
|