diff options
-rw-r--r-- | drivers/net/bonding/bond_3ad.c | 16 | ||||
-rw-r--r-- | drivers/net/bonding/bond_main.c | 115 | ||||
-rw-r--r-- | drivers/net/bonding/bonding.h | 47 |
3 files changed, 120 insertions, 58 deletions
diff --git a/drivers/net/bonding/bond_3ad.c b/drivers/net/bonding/bond_3ad.c index 6d20fbde8d43..dcde56057fe1 100644 --- a/drivers/net/bonding/bond_3ad.c +++ b/drivers/net/bonding/bond_3ad.c | |||
@@ -181,7 +181,7 @@ static inline int __agg_has_partner(struct aggregator *agg) | |||
181 | */ | 181 | */ |
182 | static inline void __disable_port(struct port *port) | 182 | static inline void __disable_port(struct port *port) |
183 | { | 183 | { |
184 | bond_set_slave_inactive_flags(port->slave); | 184 | bond_set_slave_inactive_flags(port->slave, BOND_SLAVE_NOTIFY_LATER); |
185 | } | 185 | } |
186 | 186 | ||
187 | /** | 187 | /** |
@@ -193,7 +193,7 @@ static inline void __enable_port(struct port *port) | |||
193 | struct slave *slave = port->slave; | 193 | struct slave *slave = port->slave; |
194 | 194 | ||
195 | if ((slave->link == BOND_LINK_UP) && IS_UP(slave->dev)) | 195 | if ((slave->link == BOND_LINK_UP) && IS_UP(slave->dev)) |
196 | bond_set_slave_active_flags(slave); | 196 | bond_set_slave_active_flags(slave, BOND_SLAVE_NOTIFY_LATER); |
197 | } | 197 | } |
198 | 198 | ||
199 | /** | 199 | /** |
@@ -2062,6 +2062,7 @@ void bond_3ad_state_machine_handler(struct work_struct *work) | |||
2062 | struct list_head *iter; | 2062 | struct list_head *iter; |
2063 | struct slave *slave; | 2063 | struct slave *slave; |
2064 | struct port *port; | 2064 | struct port *port; |
2065 | bool should_notify_rtnl = BOND_SLAVE_NOTIFY_LATER; | ||
2065 | 2066 | ||
2066 | read_lock(&bond->lock); | 2067 | read_lock(&bond->lock); |
2067 | rcu_read_lock(); | 2068 | rcu_read_lock(); |
@@ -2119,8 +2120,19 @@ void bond_3ad_state_machine_handler(struct work_struct *work) | |||
2119 | } | 2120 | } |
2120 | 2121 | ||
2121 | re_arm: | 2122 | re_arm: |
2123 | bond_for_each_slave_rcu(bond, slave, iter) { | ||
2124 | if (slave->should_notify) { | ||
2125 | should_notify_rtnl = BOND_SLAVE_NOTIFY_NOW; | ||
2126 | break; | ||
2127 | } | ||
2128 | } | ||
2122 | rcu_read_unlock(); | 2129 | rcu_read_unlock(); |
2123 | read_unlock(&bond->lock); | 2130 | read_unlock(&bond->lock); |
2131 | |||
2132 | if (should_notify_rtnl && rtnl_trylock()) { | ||
2133 | bond_slave_state_notify(bond); | ||
2134 | rtnl_unlock(); | ||
2135 | } | ||
2124 | queue_delayed_work(bond->wq, &bond->ad_work, ad_delta_in_ticks); | 2136 | queue_delayed_work(bond->wq, &bond->ad_work, ad_delta_in_ticks); |
2125 | } | 2137 | } |
2126 | 2138 | ||
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 1c6104d3501d..82b70ff1fd28 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c | |||
@@ -829,21 +829,25 @@ void bond_change_active_slave(struct bonding *bond, struct slave *new_active) | |||
829 | if (bond_is_lb(bond)) { | 829 | if (bond_is_lb(bond)) { |
830 | bond_alb_handle_active_change(bond, new_active); | 830 | bond_alb_handle_active_change(bond, new_active); |
831 | if (old_active) | 831 | if (old_active) |
832 | bond_set_slave_inactive_flags(old_active); | 832 | bond_set_slave_inactive_flags(old_active, |
833 | BOND_SLAVE_NOTIFY_NOW); | ||
833 | if (new_active) | 834 | if (new_active) |
834 | bond_set_slave_active_flags(new_active); | 835 | bond_set_slave_active_flags(new_active, |
836 | BOND_SLAVE_NOTIFY_NOW); | ||
835 | } else { | 837 | } else { |
836 | rcu_assign_pointer(bond->curr_active_slave, new_active); | 838 | rcu_assign_pointer(bond->curr_active_slave, new_active); |
837 | } | 839 | } |
838 | 840 | ||
839 | if (bond->params.mode == BOND_MODE_ACTIVEBACKUP) { | 841 | if (bond->params.mode == BOND_MODE_ACTIVEBACKUP) { |
840 | if (old_active) | 842 | if (old_active) |
841 | bond_set_slave_inactive_flags(old_active); | 843 | bond_set_slave_inactive_flags(old_active, |
844 | BOND_SLAVE_NOTIFY_NOW); | ||
842 | 845 | ||
843 | if (new_active) { | 846 | if (new_active) { |
844 | bool should_notify_peers = false; | 847 | bool should_notify_peers = false; |
845 | 848 | ||
846 | bond_set_slave_active_flags(new_active); | 849 | bond_set_slave_active_flags(new_active, |
850 | BOND_SLAVE_NOTIFY_NOW); | ||
847 | 851 | ||
848 | if (bond->params.fail_over_mac) | 852 | if (bond->params.fail_over_mac) |
849 | bond_do_fail_over_mac(bond, new_active, | 853 | bond_do_fail_over_mac(bond, new_active, |
@@ -1463,14 +1467,15 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) | |||
1463 | 1467 | ||
1464 | switch (bond->params.mode) { | 1468 | switch (bond->params.mode) { |
1465 | case BOND_MODE_ACTIVEBACKUP: | 1469 | case BOND_MODE_ACTIVEBACKUP: |
1466 | bond_set_slave_inactive_flags(new_slave); | 1470 | bond_set_slave_inactive_flags(new_slave, |
1471 | BOND_SLAVE_NOTIFY_NOW); | ||
1467 | break; | 1472 | break; |
1468 | case BOND_MODE_8023AD: | 1473 | case BOND_MODE_8023AD: |
1469 | /* in 802.3ad mode, the internal mechanism | 1474 | /* in 802.3ad mode, the internal mechanism |
1470 | * will activate the slaves in the selected | 1475 | * will activate the slaves in the selected |
1471 | * aggregator | 1476 | * aggregator |
1472 | */ | 1477 | */ |
1473 | bond_set_slave_inactive_flags(new_slave); | 1478 | bond_set_slave_inactive_flags(new_slave, BOND_SLAVE_NOTIFY_NOW); |
1474 | /* if this is the first slave */ | 1479 | /* if this is the first slave */ |
1475 | if (!prev_slave) { | 1480 | if (!prev_slave) { |
1476 | SLAVE_AD_INFO(new_slave).id = 1; | 1481 | SLAVE_AD_INFO(new_slave).id = 1; |
@@ -1488,7 +1493,7 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) | |||
1488 | case BOND_MODE_TLB: | 1493 | case BOND_MODE_TLB: |
1489 | case BOND_MODE_ALB: | 1494 | case BOND_MODE_ALB: |
1490 | bond_set_active_slave(new_slave); | 1495 | bond_set_active_slave(new_slave); |
1491 | bond_set_slave_inactive_flags(new_slave); | 1496 | bond_set_slave_inactive_flags(new_slave, BOND_SLAVE_NOTIFY_NOW); |
1492 | break; | 1497 | break; |
1493 | default: | 1498 | default: |
1494 | pr_debug("This slave is always active in trunk mode\n"); | 1499 | pr_debug("This slave is always active in trunk mode\n"); |
@@ -2015,7 +2020,8 @@ static void bond_miimon_commit(struct bonding *bond) | |||
2015 | 2020 | ||
2016 | if (bond->params.mode == BOND_MODE_ACTIVEBACKUP || | 2021 | if (bond->params.mode == BOND_MODE_ACTIVEBACKUP || |
2017 | bond->params.mode == BOND_MODE_8023AD) | 2022 | bond->params.mode == BOND_MODE_8023AD) |
2018 | bond_set_slave_inactive_flags(slave); | 2023 | bond_set_slave_inactive_flags(slave, |
2024 | BOND_SLAVE_NOTIFY_NOW); | ||
2019 | 2025 | ||
2020 | pr_info("%s: link status definitely down for interface %s, disabling it\n", | 2026 | pr_info("%s: link status definitely down for interface %s, disabling it\n", |
2021 | bond->dev->name, slave->dev->name); | 2027 | bond->dev->name, slave->dev->name); |
@@ -2562,7 +2568,8 @@ static void bond_ab_arp_commit(struct bonding *bond) | |||
2562 | slave->link = BOND_LINK_UP; | 2568 | slave->link = BOND_LINK_UP; |
2563 | if (bond->current_arp_slave) { | 2569 | if (bond->current_arp_slave) { |
2564 | bond_set_slave_inactive_flags( | 2570 | bond_set_slave_inactive_flags( |
2565 | bond->current_arp_slave); | 2571 | bond->current_arp_slave, |
2572 | BOND_SLAVE_NOTIFY_NOW); | ||
2566 | bond->current_arp_slave = NULL; | 2573 | bond->current_arp_slave = NULL; |
2567 | } | 2574 | } |
2568 | 2575 | ||
@@ -2582,7 +2589,8 @@ static void bond_ab_arp_commit(struct bonding *bond) | |||
2582 | slave->link_failure_count++; | 2589 | slave->link_failure_count++; |
2583 | 2590 | ||
2584 | slave->link = BOND_LINK_DOWN; | 2591 | slave->link = BOND_LINK_DOWN; |
2585 | bond_set_slave_inactive_flags(slave); | 2592 | bond_set_slave_inactive_flags(slave, |
2593 | BOND_SLAVE_NOTIFY_NOW); | ||
2586 | 2594 | ||
2587 | pr_info("%s: link status definitely down for interface %s, disabling it\n", | 2595 | pr_info("%s: link status definitely down for interface %s, disabling it\n", |
2588 | bond->dev->name, slave->dev->name); | 2596 | bond->dev->name, slave->dev->name); |
@@ -2615,17 +2623,17 @@ do_failover: | |||
2615 | 2623 | ||
2616 | /* | 2624 | /* |
2617 | * Send ARP probes for active-backup mode ARP monitor. | 2625 | * Send ARP probes for active-backup mode ARP monitor. |
2626 | * | ||
2627 | * Called with rcu_read_lock hold. | ||
2618 | */ | 2628 | */ |
2619 | static bool bond_ab_arp_probe(struct bonding *bond) | 2629 | static bool bond_ab_arp_probe(struct bonding *bond) |
2620 | { | 2630 | { |
2621 | struct slave *slave, *before = NULL, *new_slave = NULL, | 2631 | struct slave *slave, *before = NULL, *new_slave = NULL, |
2622 | *curr_arp_slave, *curr_active_slave; | 2632 | *curr_arp_slave = rcu_dereference(bond->current_arp_slave), |
2633 | *curr_active_slave = rcu_dereference(bond->curr_active_slave); | ||
2623 | struct list_head *iter; | 2634 | struct list_head *iter; |
2624 | bool found = false; | 2635 | bool found = false; |
2625 | 2636 | bool should_notify_rtnl = BOND_SLAVE_NOTIFY_LATER; | |
2626 | rcu_read_lock(); | ||
2627 | curr_arp_slave = rcu_dereference(bond->current_arp_slave); | ||
2628 | curr_active_slave = rcu_dereference(bond->curr_active_slave); | ||
2629 | 2637 | ||
2630 | if (curr_arp_slave && curr_active_slave) | 2638 | if (curr_arp_slave && curr_active_slave) |
2631 | pr_info("PROBE: c_arp %s && cas %s BAD\n", | 2639 | pr_info("PROBE: c_arp %s && cas %s BAD\n", |
@@ -2634,32 +2642,23 @@ static bool bond_ab_arp_probe(struct bonding *bond) | |||
2634 | 2642 | ||
2635 | if (curr_active_slave) { | 2643 | if (curr_active_slave) { |
2636 | bond_arp_send_all(bond, curr_active_slave); | 2644 | bond_arp_send_all(bond, curr_active_slave); |
2637 | rcu_read_unlock(); | 2645 | return should_notify_rtnl; |
2638 | return true; | ||
2639 | } | 2646 | } |
2640 | rcu_read_unlock(); | ||
2641 | 2647 | ||
2642 | /* if we don't have a curr_active_slave, search for the next available | 2648 | /* if we don't have a curr_active_slave, search for the next available |
2643 | * backup slave from the current_arp_slave and make it the candidate | 2649 | * backup slave from the current_arp_slave and make it the candidate |
2644 | * for becoming the curr_active_slave | 2650 | * for becoming the curr_active_slave |
2645 | */ | 2651 | */ |
2646 | 2652 | ||
2647 | if (!rtnl_trylock()) | ||
2648 | return false; | ||
2649 | /* curr_arp_slave might have gone away */ | ||
2650 | curr_arp_slave = ACCESS_ONCE(bond->current_arp_slave); | ||
2651 | |||
2652 | if (!curr_arp_slave) { | 2653 | if (!curr_arp_slave) { |
2653 | curr_arp_slave = bond_first_slave(bond); | 2654 | curr_arp_slave = bond_first_slave_rcu(bond); |
2654 | if (!curr_arp_slave) { | 2655 | if (!curr_arp_slave) |
2655 | rtnl_unlock(); | 2656 | return should_notify_rtnl; |
2656 | return true; | ||
2657 | } | ||
2658 | } | 2657 | } |
2659 | 2658 | ||
2660 | bond_set_slave_inactive_flags(curr_arp_slave); | 2659 | bond_set_slave_inactive_flags(curr_arp_slave, BOND_SLAVE_NOTIFY_LATER); |
2661 | 2660 | ||
2662 | bond_for_each_slave(bond, slave, iter) { | 2661 | bond_for_each_slave_rcu(bond, slave, iter) { |
2663 | if (!found && !before && IS_UP(slave->dev)) | 2662 | if (!found && !before && IS_UP(slave->dev)) |
2664 | before = slave; | 2663 | before = slave; |
2665 | 2664 | ||
@@ -2677,7 +2676,8 @@ static bool bond_ab_arp_probe(struct bonding *bond) | |||
2677 | if (slave->link_failure_count < UINT_MAX) | 2676 | if (slave->link_failure_count < UINT_MAX) |
2678 | slave->link_failure_count++; | 2677 | slave->link_failure_count++; |
2679 | 2678 | ||
2680 | bond_set_slave_inactive_flags(slave); | 2679 | bond_set_slave_inactive_flags(slave, |
2680 | BOND_SLAVE_NOTIFY_LATER); | ||
2681 | 2681 | ||
2682 | pr_info("%s: backup interface %s is now down.\n", | 2682 | pr_info("%s: backup interface %s is now down.\n", |
2683 | bond->dev->name, slave->dev->name); | 2683 | bond->dev->name, slave->dev->name); |
@@ -2689,26 +2689,31 @@ static bool bond_ab_arp_probe(struct bonding *bond) | |||
2689 | if (!new_slave && before) | 2689 | if (!new_slave && before) |
2690 | new_slave = before; | 2690 | new_slave = before; |
2691 | 2691 | ||
2692 | if (!new_slave) { | 2692 | if (!new_slave) |
2693 | rtnl_unlock(); | 2693 | goto check_state; |
2694 | return true; | ||
2695 | } | ||
2696 | 2694 | ||
2697 | new_slave->link = BOND_LINK_BACK; | 2695 | new_slave->link = BOND_LINK_BACK; |
2698 | bond_set_slave_active_flags(new_slave); | 2696 | bond_set_slave_active_flags(new_slave, BOND_SLAVE_NOTIFY_LATER); |
2699 | bond_arp_send_all(bond, new_slave); | 2697 | bond_arp_send_all(bond, new_slave); |
2700 | new_slave->jiffies = jiffies; | 2698 | new_slave->jiffies = jiffies; |
2701 | rcu_assign_pointer(bond->current_arp_slave, new_slave); | 2699 | rcu_assign_pointer(bond->current_arp_slave, new_slave); |
2702 | rtnl_unlock(); | ||
2703 | 2700 | ||
2704 | return true; | 2701 | check_state: |
2702 | bond_for_each_slave_rcu(bond, slave, iter) { | ||
2703 | if (slave->should_notify) { | ||
2704 | should_notify_rtnl = BOND_SLAVE_NOTIFY_NOW; | ||
2705 | break; | ||
2706 | } | ||
2707 | } | ||
2708 | return should_notify_rtnl; | ||
2705 | } | 2709 | } |
2706 | 2710 | ||
2707 | static void bond_activebackup_arp_mon(struct work_struct *work) | 2711 | static void bond_activebackup_arp_mon(struct work_struct *work) |
2708 | { | 2712 | { |
2709 | struct bonding *bond = container_of(work, struct bonding, | 2713 | struct bonding *bond = container_of(work, struct bonding, |
2710 | arp_work.work); | 2714 | arp_work.work); |
2711 | bool should_notify_peers = false, should_commit = false; | 2715 | bool should_notify_peers = false; |
2716 | bool should_notify_rtnl = false; | ||
2712 | int delta_in_ticks; | 2717 | int delta_in_ticks; |
2713 | 2718 | ||
2714 | delta_in_ticks = msecs_to_jiffies(bond->params.arp_interval); | 2719 | delta_in_ticks = msecs_to_jiffies(bond->params.arp_interval); |
@@ -2717,11 +2722,12 @@ static void bond_activebackup_arp_mon(struct work_struct *work) | |||
2717 | goto re_arm; | 2722 | goto re_arm; |
2718 | 2723 | ||
2719 | rcu_read_lock(); | 2724 | rcu_read_lock(); |
2725 | |||
2720 | should_notify_peers = bond_should_notify_peers(bond); | 2726 | should_notify_peers = bond_should_notify_peers(bond); |
2721 | should_commit = bond_ab_arp_inspect(bond); | ||
2722 | rcu_read_unlock(); | ||
2723 | 2727 | ||
2724 | if (should_commit) { | 2728 | if (bond_ab_arp_inspect(bond)) { |
2729 | rcu_read_unlock(); | ||
2730 | |||
2725 | /* Race avoidance with bond_close flush of workqueue */ | 2731 | /* Race avoidance with bond_close flush of workqueue */ |
2726 | if (!rtnl_trylock()) { | 2732 | if (!rtnl_trylock()) { |
2727 | delta_in_ticks = 1; | 2733 | delta_in_ticks = 1; |
@@ -2730,23 +2736,28 @@ static void bond_activebackup_arp_mon(struct work_struct *work) | |||
2730 | } | 2736 | } |
2731 | 2737 | ||
2732 | bond_ab_arp_commit(bond); | 2738 | bond_ab_arp_commit(bond); |
2739 | |||
2733 | rtnl_unlock(); | 2740 | rtnl_unlock(); |
2741 | rcu_read_lock(); | ||
2734 | } | 2742 | } |
2735 | 2743 | ||
2736 | if (!bond_ab_arp_probe(bond)) { | 2744 | should_notify_rtnl = bond_ab_arp_probe(bond); |
2737 | /* rtnl locking failed, re-arm */ | 2745 | rcu_read_unlock(); |
2738 | delta_in_ticks = 1; | ||
2739 | should_notify_peers = false; | ||
2740 | } | ||
2741 | 2746 | ||
2742 | re_arm: | 2747 | re_arm: |
2743 | if (bond->params.arp_interval) | 2748 | if (bond->params.arp_interval) |
2744 | queue_delayed_work(bond->wq, &bond->arp_work, delta_in_ticks); | 2749 | queue_delayed_work(bond->wq, &bond->arp_work, delta_in_ticks); |
2745 | 2750 | ||
2746 | if (should_notify_peers) { | 2751 | if (should_notify_peers || should_notify_rtnl) { |
2747 | if (!rtnl_trylock()) | 2752 | if (!rtnl_trylock()) |
2748 | return; | 2753 | return; |
2749 | call_netdevice_notifiers(NETDEV_NOTIFY_PEERS, bond->dev); | 2754 | |
2755 | if (should_notify_peers) | ||
2756 | call_netdevice_notifiers(NETDEV_NOTIFY_PEERS, | ||
2757 | bond->dev); | ||
2758 | if (should_notify_rtnl) | ||
2759 | bond_slave_state_notify(bond); | ||
2760 | |||
2750 | rtnl_unlock(); | 2761 | rtnl_unlock(); |
2751 | } | 2762 | } |
2752 | } | 2763 | } |
@@ -3046,9 +3057,11 @@ static int bond_open(struct net_device *bond_dev) | |||
3046 | bond_for_each_slave(bond, slave, iter) { | 3057 | bond_for_each_slave(bond, slave, iter) { |
3047 | if ((bond->params.mode == BOND_MODE_ACTIVEBACKUP) | 3058 | if ((bond->params.mode == BOND_MODE_ACTIVEBACKUP) |
3048 | && (slave != bond->curr_active_slave)) { | 3059 | && (slave != bond->curr_active_slave)) { |
3049 | bond_set_slave_inactive_flags(slave); | 3060 | bond_set_slave_inactive_flags(slave, |
3061 | BOND_SLAVE_NOTIFY_NOW); | ||
3050 | } else { | 3062 | } else { |
3051 | bond_set_slave_active_flags(slave); | 3063 | bond_set_slave_active_flags(slave, |
3064 | BOND_SLAVE_NOTIFY_NOW); | ||
3052 | } | 3065 | } |
3053 | } | 3066 | } |
3054 | read_unlock(&bond->curr_slave_lock); | 3067 | read_unlock(&bond->curr_slave_lock); |
diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h index 86ccfb9f71cc..2b0fdec695f7 100644 --- a/drivers/net/bonding/bonding.h +++ b/drivers/net/bonding/bonding.h | |||
@@ -195,7 +195,8 @@ struct slave { | |||
195 | s8 new_link; | 195 | s8 new_link; |
196 | u8 backup:1, /* indicates backup slave. Value corresponds with | 196 | u8 backup:1, /* indicates backup slave. Value corresponds with |
197 | BOND_STATE_ACTIVE and BOND_STATE_BACKUP */ | 197 | BOND_STATE_ACTIVE and BOND_STATE_BACKUP */ |
198 | inactive:1; /* indicates inactive slave */ | 198 | inactive:1, /* indicates inactive slave */ |
199 | should_notify:1; /* indicateds whether the state changed */ | ||
199 | u8 duplex; | 200 | u8 duplex; |
200 | u32 original_mtu; | 201 | u32 original_mtu; |
201 | u32 link_failure_count; | 202 | u32 link_failure_count; |
@@ -303,6 +304,24 @@ static inline void bond_set_backup_slave(struct slave *slave) | |||
303 | } | 304 | } |
304 | } | 305 | } |
305 | 306 | ||
307 | static inline void bond_set_slave_state(struct slave *slave, | ||
308 | int slave_state, bool notify) | ||
309 | { | ||
310 | if (slave->backup == slave_state) | ||
311 | return; | ||
312 | |||
313 | slave->backup = slave_state; | ||
314 | if (notify) { | ||
315 | rtmsg_ifinfo(RTM_NEWLINK, slave->dev, 0, GFP_KERNEL); | ||
316 | slave->should_notify = 0; | ||
317 | } else { | ||
318 | if (slave->should_notify) | ||
319 | slave->should_notify = 0; | ||
320 | else | ||
321 | slave->should_notify = 1; | ||
322 | } | ||
323 | } | ||
324 | |||
306 | static inline void bond_slave_state_change(struct bonding *bond) | 325 | static inline void bond_slave_state_change(struct bonding *bond) |
307 | { | 326 | { |
308 | struct list_head *iter; | 327 | struct list_head *iter; |
@@ -316,6 +335,19 @@ static inline void bond_slave_state_change(struct bonding *bond) | |||
316 | } | 335 | } |
317 | } | 336 | } |
318 | 337 | ||
338 | static inline void bond_slave_state_notify(struct bonding *bond) | ||
339 | { | ||
340 | struct list_head *iter; | ||
341 | struct slave *tmp; | ||
342 | |||
343 | bond_for_each_slave(bond, tmp, iter) { | ||
344 | if (tmp->should_notify) { | ||
345 | rtmsg_ifinfo(RTM_NEWLINK, tmp->dev, 0, GFP_KERNEL); | ||
346 | tmp->should_notify = 0; | ||
347 | } | ||
348 | } | ||
349 | } | ||
350 | |||
319 | static inline int bond_slave_state(struct slave *slave) | 351 | static inline int bond_slave_state(struct slave *slave) |
320 | { | 352 | { |
321 | return slave->backup; | 353 | return slave->backup; |
@@ -343,6 +375,9 @@ static inline bool bond_is_active_slave(struct slave *slave) | |||
343 | #define BOND_ARP_VALIDATE_ALL (BOND_ARP_VALIDATE_ACTIVE | \ | 375 | #define BOND_ARP_VALIDATE_ALL (BOND_ARP_VALIDATE_ACTIVE | \ |
344 | BOND_ARP_VALIDATE_BACKUP) | 376 | BOND_ARP_VALIDATE_BACKUP) |
345 | 377 | ||
378 | #define BOND_SLAVE_NOTIFY_NOW true | ||
379 | #define BOND_SLAVE_NOTIFY_LATER false | ||
380 | |||
346 | static inline int slave_do_arp_validate(struct bonding *bond, | 381 | static inline int slave_do_arp_validate(struct bonding *bond, |
347 | struct slave *slave) | 382 | struct slave *slave) |
348 | { | 383 | { |
@@ -394,17 +429,19 @@ static inline void bond_netpoll_send_skb(const struct slave *slave, | |||
394 | } | 429 | } |
395 | #endif | 430 | #endif |
396 | 431 | ||
397 | static inline void bond_set_slave_inactive_flags(struct slave *slave) | 432 | static inline void bond_set_slave_inactive_flags(struct slave *slave, |
433 | bool notify) | ||
398 | { | 434 | { |
399 | if (!bond_is_lb(slave->bond)) | 435 | if (!bond_is_lb(slave->bond)) |
400 | bond_set_backup_slave(slave); | 436 | bond_set_slave_state(slave, BOND_STATE_BACKUP, notify); |
401 | if (!slave->bond->params.all_slaves_active) | 437 | if (!slave->bond->params.all_slaves_active) |
402 | slave->inactive = 1; | 438 | slave->inactive = 1; |
403 | } | 439 | } |
404 | 440 | ||
405 | static inline void bond_set_slave_active_flags(struct slave *slave) | 441 | static inline void bond_set_slave_active_flags(struct slave *slave, |
442 | bool notify) | ||
406 | { | 443 | { |
407 | bond_set_active_slave(slave); | 444 | bond_set_slave_state(slave, BOND_STATE_ACTIVE, notify); |
408 | slave->inactive = 0; | 445 | slave->inactive = 0; |
409 | } | 446 | } |
410 | 447 | ||