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;
        }
 
        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;
                }
 
                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;
                }
 
                        }
                }
 
-               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;
                }
 
        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 -----------------------------*/
 
 /*
        }
 
        register_netdevice_notifier(&bond_netdev_notifier);
-       register_inetaddr_notifier(&bond_inetaddr_notifier);
 out:
        return res;
 err:
 static void __exit bonding_exit(void)
 {
        unregister_netdevice_notifier(&bond_netdev_notifier);
-       unregister_inetaddr_notifier(&bond_inetaddr_notifier);
 
        bond_destroy_debugfs();
 
 
 #include <linux/cpumask.h>
 #include <linux/in6.h>
 #include <linux/netpoll.h>
+#include <linux/inetdevice.h>
 #include "bond_3ad.h"
 #include "bond_alb.h"
 
 
 struct vlan_entry {
        struct list_head vlan_list;
-       __be32 vlan_ip;
        unsigned short vlan_id;
 };
 
        struct   list_head bond_list;
        struct   netdev_hw_addr_list mc_list;
        int      (*xmit_hash_policy)(struct sk_buff *, int);
-       __be32   master_ip;
        u16      rr_tx_counter;
        struct   ad_bond_info ad_info;
        struct   alb_bond_info alb_info;
        return slave->inactive;
 }
 
+static inline __be32 bond_confirm_addr(struct net_device *dev, __be32 dst, __be32 local)
+{
+       struct in_device *in_dev;
+       __be32 addr = 0;
+
+       rcu_read_lock();
+       in_dev = __in_dev_get_rcu(dev);
+
+       if (in_dev)
+               addr = inet_confirm_addr(in_dev, dst, local, RT_SCOPE_HOST);
+
+       rcu_read_unlock();
+       return addr;
+}
+
 struct bond_net;
 
 struct vlan_entry *bond_next_vlan(struct bonding *bond, struct vlan_entry *curr);