|
@@ -2573,12 +2573,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;
|
|
|
}
|
|
|
|
|
@@ -2620,17 +2624,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;
|
|
|
}
|
|
|
|
|
@@ -2655,8 +2661,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;
|
|
|
}
|
|
|
|
|
@@ -2674,10 +2681,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;
|
|
|
}
|
|
|
|
|
@@ -3299,68 +3307,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 -----------------------------*/
|
|
|
|
|
|
/*
|
|
@@ -4929,7 +4879,6 @@ static int __init bonding_init(void)
|
|
|
}
|
|
|
|
|
|
register_netdevice_notifier(&bond_netdev_notifier);
|
|
|
- register_inetaddr_notifier(&bond_inetaddr_notifier);
|
|
|
out:
|
|
|
return res;
|
|
|
err:
|
|
@@ -4943,7 +4892,6 @@ err_link:
|
|
|
static void __exit bonding_exit(void)
|
|
|
{
|
|
|
unregister_netdevice_notifier(&bond_netdev_notifier);
|
|
|
- unregister_inetaddr_notifier(&bond_inetaddr_notifier);
|
|
|
|
|
|
bond_destroy_debugfs();
|
|
|
|