Merge tag 'split-asm_system_h-for-linus-20120328' of git://git.kernel.org/pub/scm...
[linux-2.6.git] / drivers / net / bonding / bond_main.c
index d6e8586..0c76186 100644 (file)
@@ -2572,12 +2572,16 @@ re_arm:
 static int bond_has_this_ip(struct bonding *bond, __be32 ip)
 {
        struct vlan_entry *vlan;
+       struct net_device *vlan_dev;
 
-       if (ip == bond->master_ip)
+       if (ip == bond_confirm_addr(bond->dev, 0, ip))
                return 1;
 
        list_for_each_entry(vlan, &bond->vlan_list, vlan_list) {
-               if (ip == vlan->vlan_ip)
+               rcu_read_lock();
+               vlan_dev = __vlan_find_dev_deep(bond->dev, vlan->vlan_id);
+               rcu_read_unlock();
+               if (vlan_dev && ip == bond_confirm_addr(vlan_dev, 0, ip))
                        return 1;
        }
 
@@ -2619,17 +2623,19 @@ static void bond_arp_send_all(struct bonding *bond, struct slave *slave)
        int i, vlan_id;
        __be32 *targets = bond->params.arp_targets;
        struct vlan_entry *vlan;
-       struct net_device *vlan_dev;
+       struct net_device *vlan_dev = NULL;
        struct rtable *rt;
 
        for (i = 0; (i < BOND_MAX_ARP_TARGETS); i++) {
+               __be32 addr;
                if (!targets[i])
                        break;
                pr_debug("basa: target %x\n", targets[i]);
                if (!bond_vlan_used(bond)) {
                        pr_debug("basa: empty vlan: arp_send\n");
+                       addr = bond_confirm_addr(bond->dev, targets[i], 0);
                        bond_arp_send(slave->dev, ARPOP_REQUEST, targets[i],
-                                     bond->master_ip, 0);
+                                     addr, 0);
                        continue;
                }
 
@@ -2654,8 +2660,9 @@ static void bond_arp_send_all(struct bonding *bond, struct slave *slave)
                if (rt->dst.dev == bond->dev) {
                        ip_rt_put(rt);
                        pr_debug("basa: rtdev == bond->dev: arp_send\n");
+                       addr = bond_confirm_addr(bond->dev, targets[i], 0);
                        bond_arp_send(slave->dev, ARPOP_REQUEST, targets[i],
-                                     bond->master_ip, 0);
+                                     addr, 0);
                        continue;
                }
 
@@ -2673,10 +2680,11 @@ static void bond_arp_send_all(struct bonding *bond, struct slave *slave)
                        }
                }
 
-               if (vlan_id) {
+               if (vlan_id && vlan_dev) {
                        ip_rt_put(rt);
+                       addr = bond_confirm_addr(vlan_dev, targets[i], 0);
                        bond_arp_send(slave->dev, ARPOP_REQUEST, targets[i],
-                                     vlan->vlan_ip, vlan_id);
+                                     addr, vlan_id);
                        continue;
                }
 
@@ -3298,68 +3306,10 @@ static int bond_netdev_event(struct notifier_block *this,
        return NOTIFY_DONE;
 }
 
-/*
- * bond_inetaddr_event: handle inetaddr notifier chain events.
- *
- * We keep track of device IPs primarily to use as source addresses in
- * ARP monitor probes (rather than spewing out broadcasts all the time).
- *
- * We track one IP for the main device (if it has one), plus one per VLAN.
- */
-static int bond_inetaddr_event(struct notifier_block *this, unsigned long event, void *ptr)
-{
-       struct in_ifaddr *ifa = ptr;
-       struct net_device *vlan_dev, *event_dev = ifa->ifa_dev->dev;
-       struct bond_net *bn = net_generic(dev_net(event_dev), bond_net_id);
-       struct bonding *bond;
-       struct vlan_entry *vlan;
-
-       /* we only care about primary address */
-       if(ifa->ifa_flags & IFA_F_SECONDARY)
-               return NOTIFY_DONE;
-
-       list_for_each_entry(bond, &bn->dev_list, bond_list) {
-               if (bond->dev == event_dev) {
-                       switch (event) {
-                       case NETDEV_UP:
-                               bond->master_ip = ifa->ifa_local;
-                               return NOTIFY_OK;
-                       case NETDEV_DOWN:
-                               bond->master_ip = 0;
-                               return NOTIFY_OK;
-                       default:
-                               return NOTIFY_DONE;
-                       }
-               }
-
-               list_for_each_entry(vlan, &bond->vlan_list, vlan_list) {
-                       vlan_dev = __vlan_find_dev_deep(bond->dev,
-                                                       vlan->vlan_id);
-                       if (vlan_dev == event_dev) {
-                               switch (event) {
-                               case NETDEV_UP:
-                                       vlan->vlan_ip = ifa->ifa_local;
-                                       return NOTIFY_OK;
-                               case NETDEV_DOWN:
-                                       vlan->vlan_ip = 0;
-                                       return NOTIFY_OK;
-                               default:
-                                       return NOTIFY_DONE;
-                               }
-                       }
-               }
-       }
-       return NOTIFY_DONE;
-}
-
 static struct notifier_block bond_netdev_notifier = {
        .notifier_call = bond_netdev_event,
 };
 
-static struct notifier_block bond_inetaddr_notifier = {
-       .notifier_call = bond_inetaddr_event,
-};
-
 /*---------------------------- Hashing Policies -----------------------------*/
 
 /*
@@ -4928,7 +4878,6 @@ static int __init bonding_init(void)
        }
 
        register_netdevice_notifier(&bond_netdev_notifier);
-       register_inetaddr_notifier(&bond_inetaddr_notifier);
 out:
        return res;
 err:
@@ -4942,7 +4891,6 @@ err_link:
 static void __exit bonding_exit(void)
 {
        unregister_netdevice_notifier(&bond_netdev_notifier);
-       unregister_inetaddr_notifier(&bond_inetaddr_notifier);
 
        bond_destroy_debugfs();