]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
bonding: 3ad: fix carrier when no usable slaves
authorLouis Scalbert <louis.scalbert@6wind.com>
Wed, 3 Jun 2026 15:03:29 +0000 (17:03 +0200)
committerJakub Kicinski <kuba@kernel.org>
Wed, 10 Jun 2026 14:53:33 +0000 (07:53 -0700)
Apply the "lacp_strict" configuration from the previous commit.

"lacp_strict" mode "on" asserts that the bonding master carrier is up
only when at least 'min_links' slaves are in the Collecting_Distributing
state.

Fixes: 655f8919d549 ("bonding: add min links parameter to 802.3ad")
Signed-off-by: Louis Scalbert <louis.scalbert@6wind.com>
Acked-by: Jay Vosburgh <jv@jvosburgh.net>
Link: https://patch.msgid.link/20260603150331.1919611-5-louis.scalbert@6wind.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
drivers/net/bonding/bond_3ad.c
drivers/net/bonding/bond_options.c

index 985ef66dc3331e89458c9951a222d140c2275fb9..51d86e3d34db874dd38ed7163b57f2bf400e365c 100644 (file)
@@ -745,6 +745,21 @@ static void __set_agg_ports_ready(struct aggregator *aggregator, int val)
        }
 }
 
+static int __agg_usable_ports(struct aggregator *agg)
+{
+       struct port *port;
+       int valid = 0;
+
+       for (port = agg->lag_ports; port;
+            port = port->next_port_in_aggregator) {
+               if (port->actor_oper_port_state & LACP_STATE_COLLECTING &&
+                   port->actor_oper_port_state & LACP_STATE_DISTRIBUTING)
+                       valid++;
+       }
+
+       return valid;
+}
+
 static int __agg_active_ports(struct aggregator *agg)
 {
        struct port *port;
@@ -1179,10 +1194,10 @@ static void ad_mux_machine(struct port *port, bool *update_slave_arr)
                switch (port->sm_mux_state) {
                case AD_MUX_DETACHED:
                        port->actor_oper_port_state &= ~LACP_STATE_SYNCHRONIZATION;
-                       ad_disable_collecting_distributing(port,
-                                                          update_slave_arr);
                        port->actor_oper_port_state &= ~LACP_STATE_COLLECTING;
                        port->actor_oper_port_state &= ~LACP_STATE_DISTRIBUTING;
+                       ad_disable_collecting_distributing(port,
+                                                          update_slave_arr);
                        port->ntt = true;
                        break;
                case AD_MUX_WAITING:
@@ -2107,6 +2122,7 @@ static void ad_disable_distributing(struct port *port, bool *update_slave_arr)
                          port->actor_port_number,
                          aggregator->aggregator_identifier);
                __disable_distributing_port(port);
+               bond_3ad_set_carrier(port->slave->bond);
                /* Slave array needs an update */
                *update_slave_arr = true;
        }
@@ -2130,6 +2146,7 @@ static void ad_enable_collecting_distributing(struct port *port,
                          port->actor_port_number,
                          aggregator->aggregator_identifier);
                __enable_port(port);
+               bond_3ad_set_carrier(port->slave->bond);
                /* Slave array needs update */
                *update_slave_arr = true;
                /* Should notify peers if possible */
@@ -2153,6 +2170,7 @@ static void ad_disable_collecting_distributing(struct port *port,
                          port->actor_port_number,
                          aggregator->aggregator_identifier);
                __disable_port(port);
+               bond_3ad_set_carrier(port->slave->bond);
                /* Slave array needs an update */
                *update_slave_arr = true;
        }
@@ -2832,7 +2850,9 @@ int bond_3ad_set_carrier(struct bonding *bond)
        active = __get_active_agg(&(SLAVE_AD_INFO(first_slave)->aggregator));
        if (active) {
                /* are enough slaves available to consider link up? */
-               if (__agg_active_ports(active) < bond->params.min_links) {
+               if ((bond->params.lacp_strict ? __agg_usable_ports(active)
+                                       : __agg_active_ports(active)) <
+                   bond->params.min_links) {
                        if (netif_carrier_ok(bond->dev)) {
                                netif_carrier_off(bond->dev);
                                goto out;
index f01b3baa57b4e1138a9d3ea7ee173e6de4a880fb..e590c8dee86e1e7168e400b1321fc22c8f75b87c 100644 (file)
@@ -1707,6 +1707,7 @@ static int bond_option_lacp_strict_set(struct bonding *bond,
        netdev_dbg(bond->dev, "Setting LACP fallback to %s (%llu)\n",
                   newval->string, newval->value);
        bond->params.lacp_strict = newval->value;
+       bond_3ad_set_carrier(bond);
 
        return 0;
 }