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 |
