diff options
-rw-r--r-- | drivers/net/bonding/bond_main.c | 82 | ||||
-rw-r--r-- | drivers/net/bonding/bonding.h | 18 | ||||
-rw-r--r-- | net/ipv4/devinet.c | 1 |
3 files changed, 32 insertions, 69 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 | ||
diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h index 1aecc37e5b4d..9f2bae6616d3 100644 --- a/drivers/net/bonding/bonding.h +++ b/drivers/net/bonding/bonding.h | |||
@@ -21,6 +21,7 @@ | |||
21 | #include <linux/cpumask.h> | 21 | #include <linux/cpumask.h> |
22 | #include <linux/in6.h> | 22 | #include <linux/in6.h> |
23 | #include <linux/netpoll.h> | 23 | #include <linux/netpoll.h> |
24 | #include <linux/inetdevice.h> | ||
24 | #include "bond_3ad.h" | 25 | #include "bond_3ad.h" |
25 | #include "bond_alb.h" | 26 | #include "bond_alb.h" |
26 | 27 | ||
@@ -166,7 +167,6 @@ struct bond_parm_tbl { | |||
166 | 167 | ||
167 | struct vlan_entry { | 168 | struct vlan_entry { |
168 | struct list_head vlan_list; | 169 | struct list_head vlan_list; |
169 | __be32 vlan_ip; | ||
170 | unsigned short vlan_id; | 170 | unsigned short vlan_id; |
171 | }; | 171 | }; |
172 | 172 | ||
@@ -232,7 +232,6 @@ struct bonding { | |||
232 | struct list_head bond_list; | 232 | struct list_head bond_list; |
233 | struct netdev_hw_addr_list mc_list; | 233 | struct netdev_hw_addr_list mc_list; |
234 | int (*xmit_hash_policy)(struct sk_buff *, int); | 234 | int (*xmit_hash_policy)(struct sk_buff *, int); |
235 | __be32 master_ip; | ||
236 | u16 rr_tx_counter; | 235 | u16 rr_tx_counter; |
237 | struct ad_bond_info ad_info; | 236 | struct ad_bond_info ad_info; |
238 | struct alb_bond_info alb_info; | 237 | struct alb_bond_info alb_info; |
@@ -378,6 +377,21 @@ static inline bool bond_is_slave_inactive(struct slave *slave) | |||
378 | return slave->inactive; | 377 | return slave->inactive; |
379 | } | 378 | } |
380 | 379 | ||
380 | static inline __be32 bond_confirm_addr(struct net_device *dev, __be32 dst, __be32 local) | ||
381 | { | ||
382 | struct in_device *in_dev; | ||
383 | __be32 addr = 0; | ||
384 | |||
385 | rcu_read_lock(); | ||
386 | in_dev = __in_dev_get_rcu(dev); | ||
387 | |||
388 | if (in_dev) | ||
389 | addr = inet_confirm_addr(in_dev, dst, local, RT_SCOPE_HOST); | ||
390 | |||
391 | rcu_read_unlock(); | ||
392 | return addr; | ||
393 | } | ||
394 | |||
381 | struct bond_net; | 395 | struct bond_net; |
382 | 396 | ||
383 | struct vlan_entry *bond_next_vlan(struct bonding *bond, struct vlan_entry *curr); | 397 | struct vlan_entry *bond_next_vlan(struct bonding *bond, struct vlan_entry *curr); |
diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c index e41c40f48cfe..d4fad5c77447 100644 --- a/net/ipv4/devinet.c +++ b/net/ipv4/devinet.c | |||
@@ -1079,6 +1079,7 @@ __be32 inet_confirm_addr(struct in_device *in_dev, | |||
1079 | 1079 | ||
1080 | return addr; | 1080 | return addr; |
1081 | } | 1081 | } |
1082 | EXPORT_SYMBOL(inet_confirm_addr); | ||
1082 | 1083 | ||
1083 | /* | 1084 | /* |
1084 | * Device notifier | 1085 | * Device notifier |