diff options
Diffstat (limited to 'drivers/net/bonding/bond_main.c')
-rw-r--r-- | drivers/net/bonding/bond_main.c | 82 |
1 files changed, 15 insertions, 67 deletions
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 0730203a19f2..b920d829692a 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c | |||
@@ -2573,12 +2573,16 @@ re_arm: | |||
2573 | static int bond_has_this_ip(struct bonding *bond, __be32 ip) | 2573 | static int bond_has_this_ip(struct bonding *bond, __be32 ip) |
2574 | { | 2574 | { |
2575 | struct vlan_entry *vlan; | 2575 | struct vlan_entry *vlan; |
2576 | struct net_device *vlan_dev; | ||
2576 | 2577 | ||
2577 | if (ip == bond->master_ip) | 2578 | if (ip == bond_confirm_addr(bond->dev, 0, ip)) |
2578 | return 1; | 2579 | return 1; |
2579 | 2580 | ||
2580 | list_for_each_entry(vlan, &bond->vlan_list, vlan_list) { | 2581 | list_for_each_entry(vlan, &bond->vlan_list, vlan_list) { |
2581 | if (ip == vlan->vlan_ip) | 2582 | rcu_read_lock(); |
2583 | vlan_dev = __vlan_find_dev_deep(bond->dev, vlan->vlan_id); | ||
2584 | rcu_read_unlock(); | ||
2585 | if (vlan_dev && ip == bond_confirm_addr(vlan_dev, 0, ip)) | ||
2582 | return 1; | 2586 | return 1; |
2583 | } | 2587 | } |
2584 | 2588 | ||
@@ -2620,17 +2624,19 @@ static void bond_arp_send_all(struct bonding *bond, struct slave *slave) | |||
2620 | int i, vlan_id; | 2624 | int i, vlan_id; |
2621 | __be32 *targets = bond->params.arp_targets; | 2625 | __be32 *targets = bond->params.arp_targets; |
2622 | struct vlan_entry *vlan; | 2626 | struct vlan_entry *vlan; |
2623 | struct net_device *vlan_dev; | 2627 | struct net_device *vlan_dev = NULL; |
2624 | struct rtable *rt; | 2628 | struct rtable *rt; |
2625 | 2629 | ||
2626 | for (i = 0; (i < BOND_MAX_ARP_TARGETS); i++) { | 2630 | for (i = 0; (i < BOND_MAX_ARP_TARGETS); i++) { |
2631 | __be32 addr; | ||
2627 | if (!targets[i]) | 2632 | if (!targets[i]) |
2628 | break; | 2633 | break; |
2629 | pr_debug("basa: target %x\n", targets[i]); | 2634 | pr_debug("basa: target %x\n", targets[i]); |
2630 | if (!bond_vlan_used(bond)) { | 2635 | if (!bond_vlan_used(bond)) { |
2631 | pr_debug("basa: empty vlan: arp_send\n"); | 2636 | pr_debug("basa: empty vlan: arp_send\n"); |
2637 | addr = bond_confirm_addr(bond->dev, targets[i], 0); | ||
2632 | bond_arp_send(slave->dev, ARPOP_REQUEST, targets[i], | 2638 | bond_arp_send(slave->dev, ARPOP_REQUEST, targets[i], |
2633 | bond->master_ip, 0); | 2639 | addr, 0); |
2634 | continue; | 2640 | continue; |
2635 | } | 2641 | } |
2636 | 2642 | ||
@@ -2655,8 +2661,9 @@ static void bond_arp_send_all(struct bonding *bond, struct slave *slave) | |||
2655 | if (rt->dst.dev == bond->dev) { | 2661 | if (rt->dst.dev == bond->dev) { |
2656 | ip_rt_put(rt); | 2662 | ip_rt_put(rt); |
2657 | pr_debug("basa: rtdev == bond->dev: arp_send\n"); | 2663 | pr_debug("basa: rtdev == bond->dev: arp_send\n"); |
2664 | addr = bond_confirm_addr(bond->dev, targets[i], 0); | ||
2658 | bond_arp_send(slave->dev, ARPOP_REQUEST, targets[i], | 2665 | bond_arp_send(slave->dev, ARPOP_REQUEST, targets[i], |
2659 | bond->master_ip, 0); | 2666 | addr, 0); |
2660 | continue; | 2667 | continue; |
2661 | } | 2668 | } |
2662 | 2669 | ||
@@ -2674,10 +2681,11 @@ static void bond_arp_send_all(struct bonding *bond, struct slave *slave) | |||
2674 | } | 2681 | } |
2675 | } | 2682 | } |
2676 | 2683 | ||
2677 | if (vlan_id) { | 2684 | if (vlan_id && vlan_dev) { |
2678 | ip_rt_put(rt); | 2685 | ip_rt_put(rt); |
2686 | addr = bond_confirm_addr(vlan_dev, targets[i], 0); | ||
2679 | bond_arp_send(slave->dev, ARPOP_REQUEST, targets[i], | 2687 | bond_arp_send(slave->dev, ARPOP_REQUEST, targets[i], |
2680 | vlan->vlan_ip, vlan_id); | 2688 | addr, vlan_id); |
2681 | continue; | 2689 | continue; |
2682 | } | 2690 | } |
2683 | 2691 | ||
@@ -3299,68 +3307,10 @@ static int bond_netdev_event(struct notifier_block *this, | |||
3299 | return NOTIFY_DONE; | 3307 | return NOTIFY_DONE; |
3300 | } | 3308 | } |
3301 | 3309 | ||
3302 | /* | ||
3303 | * bond_inetaddr_event: handle inetaddr notifier chain events. | ||
3304 | * | ||
3305 | * We keep track of device IPs primarily to use as source addresses in | ||
3306 | * ARP monitor probes (rather than spewing out broadcasts all the time). | ||
3307 | * | ||
3308 | * We track one IP for the main device (if it has one), plus one per VLAN. | ||
3309 | */ | ||
3310 | static int bond_inetaddr_event(struct notifier_block *this, unsigned long event, void *ptr) | ||
3311 | { | ||
3312 | struct in_ifaddr *ifa = ptr; | ||
3313 | struct net_device *vlan_dev, *event_dev = ifa->ifa_dev->dev; | ||
3314 | struct bond_net *bn = net_generic(dev_net(event_dev), bond_net_id); | ||
3315 | struct bonding *bond; | ||
3316 | struct vlan_entry *vlan; | ||
3317 | |||
3318 | /* we only care about primary address */ | ||
3319 | if(ifa->ifa_flags & IFA_F_SECONDARY) | ||
3320 | return NOTIFY_DONE; | ||
3321 | |||
3322 | list_for_each_entry(bond, &bn->dev_list, bond_list) { | ||
3323 | if (bond->dev == event_dev) { | ||
3324 | switch (event) { | ||
3325 | case NETDEV_UP: | ||
3326 | bond->master_ip = ifa->ifa_local; | ||
3327 | return NOTIFY_OK; | ||
3328 | case NETDEV_DOWN: | ||
3329 | bond->master_ip = 0; | ||
3330 | return NOTIFY_OK; | ||
3331 | default: | ||
3332 | return NOTIFY_DONE; | ||
3333 | } | ||
3334 | } | ||
3335 | |||
3336 | list_for_each_entry(vlan, &bond->vlan_list, vlan_list) { | ||
3337 | vlan_dev = __vlan_find_dev_deep(bond->dev, | ||
3338 | vlan->vlan_id); | ||
3339 | if (vlan_dev == event_dev) { | ||
3340 | switch (event) { | ||
3341 | case NETDEV_UP: | ||
3342 | vlan->vlan_ip = ifa->ifa_local; | ||
3343 | return NOTIFY_OK; | ||
3344 | case NETDEV_DOWN: | ||
3345 | vlan->vlan_ip = 0; | ||
3346 | return NOTIFY_OK; | ||
3347 | default: | ||
3348 | return NOTIFY_DONE; | ||
3349 | } | ||
3350 | } | ||
3351 | } | ||
3352 | } | ||
3353 | return NOTIFY_DONE; | ||
3354 | } | ||
3355 | |||
3356 | static struct notifier_block bond_netdev_notifier = { | 3310 | static struct notifier_block bond_netdev_notifier = { |
3357 | .notifier_call = bond_netdev_event, | 3311 | .notifier_call = bond_netdev_event, |
3358 | }; | 3312 | }; |
3359 | 3313 | ||
3360 | static struct notifier_block bond_inetaddr_notifier = { | ||
3361 | .notifier_call = bond_inetaddr_event, | ||
3362 | }; | ||
3363 | |||
3364 | /*---------------------------- Hashing Policies -----------------------------*/ | 3314 | /*---------------------------- Hashing Policies -----------------------------*/ |
3365 | 3315 | ||
3366 | /* | 3316 | /* |
@@ -4929,7 +4879,6 @@ static int __init bonding_init(void) | |||
4929 | } | 4879 | } |
4930 | 4880 | ||
4931 | register_netdevice_notifier(&bond_netdev_notifier); | 4881 | register_netdevice_notifier(&bond_netdev_notifier); |
4932 | register_inetaddr_notifier(&bond_inetaddr_notifier); | ||
4933 | out: | 4882 | out: |
4934 | return res; | 4883 | return res; |
4935 | err: | 4884 | err: |
@@ -4943,7 +4892,6 @@ err_link: | |||
4943 | static void __exit bonding_exit(void) | 4892 | static void __exit bonding_exit(void) |
4944 | { | 4893 | { |
4945 | unregister_netdevice_notifier(&bond_netdev_notifier); | 4894 | unregister_netdevice_notifier(&bond_netdev_notifier); |
4946 | unregister_inetaddr_notifier(&bond_inetaddr_notifier); | ||
4947 | 4895 | ||
4948 | bond_destroy_debugfs(); | 4896 | bond_destroy_debugfs(); |
4949 | 4897 | ||