aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/bonding
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/bonding')
-rw-r--r--drivers/net/bonding/bond_main.c76
1 files changed, 25 insertions, 51 deletions
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index 1ca73b8c139b..e4724d874e7c 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -60,6 +60,7 @@
60#include <linux/errno.h> 60#include <linux/errno.h>
61#include <linux/netdevice.h> 61#include <linux/netdevice.h>
62#include <linux/inetdevice.h> 62#include <linux/inetdevice.h>
63#include <linux/igmp.h>
63#include <linux/etherdevice.h> 64#include <linux/etherdevice.h>
64#include <linux/skbuff.h> 65#include <linux/skbuff.h>
65#include <net/sock.h> 66#include <net/sock.h>
@@ -861,6 +862,28 @@ static void bond_mc_delete(struct bonding *bond, void *addr, int alen)
861 } 862 }
862} 863}
863 864
865
866/*
867 * Retrieve the list of registered multicast addresses for the bonding
868 * device and retransmit an IGMP JOIN request to the current active
869 * slave.
870 */
871static void bond_resend_igmp_join_requests(struct bonding *bond)
872{
873 struct in_device *in_dev;
874 struct ip_mc_list *im;
875
876 rcu_read_lock();
877 in_dev = __in_dev_get_rcu(bond->dev);
878 if (in_dev) {
879 for (im = in_dev->mc_list; im; im = im->next) {
880 ip_mc_rejoin_group(im);
881 }
882 }
883
884 rcu_read_unlock();
885}
886
864/* 887/*
865 * Totally destroys the mc_list in bond 888 * Totally destroys the mc_list in bond
866 */ 889 */
@@ -874,6 +897,7 @@ static void bond_mc_list_destroy(struct bonding *bond)
874 kfree(dmi); 897 kfree(dmi);
875 dmi = bond->mc_list; 898 dmi = bond->mc_list;
876 } 899 }
900 bond->mc_list = NULL;
877} 901}
878 902
879/* 903/*
@@ -967,6 +991,7 @@ static void bond_mc_swap(struct bonding *bond, struct slave *new_active, struct
967 for (dmi = bond->dev->mc_list; dmi; dmi = dmi->next) { 991 for (dmi = bond->dev->mc_list; dmi; dmi = dmi->next) {
968 dev_mc_add(new_active->dev, dmi->dmi_addr, dmi->dmi_addrlen, 0); 992 dev_mc_add(new_active->dev, dmi->dmi_addr, dmi->dmi_addrlen, 0);
969 } 993 }
994 bond_resend_igmp_join_requests(bond);
970 } 995 }
971} 996}
972 997
@@ -4017,42 +4042,6 @@ out:
4017 return 0; 4042 return 0;
4018} 4043}
4019 4044
4020static void bond_activebackup_xmit_copy(struct sk_buff *skb,
4021 struct bonding *bond,
4022 struct slave *slave)
4023{
4024 struct sk_buff *skb2 = skb_copy(skb, GFP_ATOMIC);
4025 struct ethhdr *eth_data;
4026 u8 *hwaddr;
4027 int res;
4028
4029 if (!skb2) {
4030 printk(KERN_ERR DRV_NAME ": Error: "
4031 "bond_activebackup_xmit_copy(): skb_copy() failed\n");
4032 return;
4033 }
4034
4035 skb2->mac.raw = (unsigned char *)skb2->data;
4036 eth_data = eth_hdr(skb2);
4037
4038 /* Pick an appropriate source MAC address
4039 * -- use slave's perm MAC addr, unless used by bond
4040 * -- otherwise, borrow active slave's perm MAC addr
4041 * since that will not be used
4042 */
4043 hwaddr = slave->perm_hwaddr;
4044 if (!memcmp(eth_data->h_source, hwaddr, ETH_ALEN))
4045 hwaddr = bond->curr_active_slave->perm_hwaddr;
4046
4047 /* Set source MAC address appropriately */
4048 memcpy(eth_data->h_source, hwaddr, ETH_ALEN);
4049
4050 res = bond_dev_queue_xmit(bond, skb2, slave->dev);
4051 if (res)
4052 dev_kfree_skb(skb2);
4053
4054 return;
4055}
4056 4045
4057/* 4046/*
4058 * in active-backup mode, we know that bond->curr_active_slave is always valid if 4047 * 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
4073 if (!bond->curr_active_slave) 4062 if (!bond->curr_active_slave)
4074 goto out; 4063 goto out;
4075 4064
4076 /* Xmit IGMP frames on all slaves to ensure rapid fail-over
4077 for multicast traffic on snooping switches */
4078 if (skb->protocol == __constant_htons(ETH_P_IP) &&
4079 skb->nh.iph->protocol == IPPROTO_IGMP) {
4080 struct slave *slave, *active_slave;
4081 int i;
4082
4083 active_slave = bond->curr_active_slave;
4084 bond_for_each_slave_from_to(bond, slave, i, active_slave->next,
4085 active_slave->prev)
4086 if (IS_UP(slave->dev) &&
4087 (slave->link == BOND_LINK_UP))
4088 bond_activebackup_xmit_copy(skb, bond, slave);
4089 }
4090
4091 res = bond_dev_queue_xmit(bond, skb, bond->curr_active_slave->dev); 4065 res = bond_dev_queue_xmit(bond, skb, bond->curr_active_slave->dev);
4092 4066
4093out: 4067out: