]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
bonding: add support for per-port LACP actor priority
authorHangbin Liu <liuhangbin@gmail.com>
Tue, 2 Sep 2025 06:44:59 +0000 (06:44 +0000)
committerPaolo Abeni <pabeni@redhat.com>
Tue, 9 Sep 2025 08:56:02 +0000 (10:56 +0200)
Introduce a new netlink attribute 'actor_port_prio' to allow setting
the LACP actor port priority on a per-slave basis. This extends the
existing bonding infrastructure to support more granular control over
LACP negotiations.

The priority value is embedded in LACPDU packets and will be used by
subsequent patches to influence aggregator selection policies.

Signed-off-by: Hangbin Liu <liuhangbin@gmail.com>
Link: https://patch.msgid.link/20250902064501.360822-2-liuhangbin@gmail.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Documentation/networking/bonding.rst
drivers/net/bonding/bond_3ad.c
drivers/net/bonding/bond_netlink.c
drivers/net/bonding/bond_options.c
include/net/bond_3ad.h
include/net/bond_options.h
include/uapi/linux/if_link.h

index a2b42ae719d2d7811f848a8f842f9f0df50cc445..345b60992446e4ea6783a1917ed0d35b7a65dac8 100644 (file)
@@ -193,6 +193,15 @@ ad_actor_sys_prio
        This parameter has effect only in 802.3ad mode and is available through
        SysFs interface.
 
+actor_port_prio
+
+       In an AD system, this specifies the port priority. The allowed range
+       is 1 - 65535. If the value is not specified, it takes 255 as the
+       default value.
+
+       This parameter has effect only in 802.3ad mode and is available through
+       netlink interface.
+
 ad_actor_system
 
        In an AD system, this specifies the mac-address for the actor in
index 4edc8e6b6b649f3083e4f7eabf1331845310f7e2..67ca78923b04cf6ebe93fc7720e8b75e89936966 100644 (file)
@@ -436,6 +436,7 @@ static void __ad_actor_update_port(struct port *port)
 
        port->actor_system = BOND_AD_INFO(bond).system.sys_mac_addr;
        port->actor_system_priority = BOND_AD_INFO(bond).system.sys_priority;
+       port->actor_port_priority = SLAVE_AD_INFO(port->slave)->port_priority;
 }
 
 /* Conversions */
@@ -2209,6 +2210,9 @@ void bond_3ad_bind_slave(struct slave *slave)
 
                ad_initialize_port(port, &bond->params);
 
+               /* Port priority is initialized. Update it to slave's ad info */
+               SLAVE_AD_INFO(slave)->port_priority = port->actor_port_priority;
+
                port->slave = slave;
                port->actor_port_number = SLAVE_AD_INFO(slave)->id;
                /* key is determined according to the link speed, duplex and
index e573b34a1bbc8175b09a9bfd418789e5ae89a2c8..ba71d95a82d24e69c1c538fab685fc332cfb3b1e 100644 (file)
@@ -28,6 +28,7 @@ static size_t bond_get_slave_size(const struct net_device *bond_dev,
                nla_total_size(sizeof(u8)) +    /* IFLA_BOND_SLAVE_AD_ACTOR_OPER_PORT_STATE */
                nla_total_size(sizeof(u16)) +   /* IFLA_BOND_SLAVE_AD_PARTNER_OPER_PORT_STATE */
                nla_total_size(sizeof(s32)) +   /* IFLA_BOND_SLAVE_PRIO */
+               nla_total_size(sizeof(u16)) +   /* IFLA_BOND_SLAVE_ACTOR_PORT_PRIO */
                0;
 }
 
@@ -77,6 +78,10 @@ static int bond_fill_slave_info(struct sk_buff *skb,
                                        ad_port->partner_oper.port_state))
                                goto nla_put_failure;
                }
+
+               if (nla_put_u16(skb, IFLA_BOND_SLAVE_ACTOR_PORT_PRIO,
+                               SLAVE_AD_INFO(slave)->port_priority))
+                       goto nla_put_failure;
        }
 
        return 0;
@@ -130,6 +135,7 @@ static const struct nla_policy bond_policy[IFLA_BOND_MAX + 1] = {
 static const struct nla_policy bond_slave_policy[IFLA_BOND_SLAVE_MAX + 1] = {
        [IFLA_BOND_SLAVE_QUEUE_ID]      = { .type = NLA_U16 },
        [IFLA_BOND_SLAVE_PRIO]          = { .type = NLA_S32 },
+       [IFLA_BOND_SLAVE_ACTOR_PORT_PRIO]       = { .type = NLA_U16 },
 };
 
 static int bond_validate(struct nlattr *tb[], struct nlattr *data[],
@@ -180,6 +186,16 @@ static int bond_slave_changelink(struct net_device *bond_dev,
                        return err;
        }
 
+       if (data[IFLA_BOND_SLAVE_ACTOR_PORT_PRIO]) {
+               u16 ad_prio = nla_get_u16(data[IFLA_BOND_SLAVE_ACTOR_PORT_PRIO]);
+
+               bond_opt_slave_initval(&newval, &slave_dev, ad_prio);
+               err = __bond_opt_set(bond, BOND_OPT_ACTOR_PORT_PRIO, &newval,
+                                    data[IFLA_BOND_SLAVE_ACTOR_PORT_PRIO], extack);
+               if (err)
+                       return err;
+       }
+
        return 0;
 }
 
index c0a5eb8766b537a154429ecbae827083d37240ba..8970222723348385fba89976cdf925c5a27405a9 100644 (file)
@@ -79,6 +79,8 @@ static int bond_option_tlb_dynamic_lb_set(struct bonding *bond,
                                  const struct bond_opt_value *newval);
 static int bond_option_ad_actor_sys_prio_set(struct bonding *bond,
                                             const struct bond_opt_value *newval);
+static int bond_option_actor_port_prio_set(struct bonding *bond,
+                                          const struct bond_opt_value *newval);
 static int bond_option_ad_actor_system_set(struct bonding *bond,
                                           const struct bond_opt_value *newval);
 static int bond_option_ad_user_port_key_set(struct bonding *bond,
@@ -222,6 +224,13 @@ static const struct bond_opt_value bond_ad_actor_sys_prio_tbl[] = {
        { NULL,      -1,    0},
 };
 
+static const struct bond_opt_value bond_actor_port_prio_tbl[] = {
+       { "minval",  0,     BOND_VALFLAG_MIN},
+       { "maxval",  65535, BOND_VALFLAG_MAX},
+       { "default", 255,   BOND_VALFLAG_DEFAULT},
+       { NULL,      -1,    0},
+};
+
 static const struct bond_opt_value bond_ad_user_port_key_tbl[] = {
        { "minval",  0,     BOND_VALFLAG_MIN | BOND_VALFLAG_DEFAULT},
        { "maxval",  1023,  BOND_VALFLAG_MAX},
@@ -483,6 +492,13 @@ static const struct bond_option bond_opts[BOND_OPT_LAST] = {
                .values = bond_ad_actor_sys_prio_tbl,
                .set = bond_option_ad_actor_sys_prio_set,
        },
+       [BOND_OPT_ACTOR_PORT_PRIO] = {
+               .id = BOND_OPT_ACTOR_PORT_PRIO,
+               .name = "actor_port_prio",
+               .unsuppmodes = BOND_MODE_ALL_EX(BIT(BOND_MODE_8023AD)),
+               .values = bond_actor_port_prio_tbl,
+               .set = bond_option_actor_port_prio_set,
+       },
        [BOND_OPT_AD_ACTOR_SYSTEM] = {
                .id = BOND_OPT_AD_ACTOR_SYSTEM,
                .name = "ad_actor_system",
@@ -1812,6 +1828,26 @@ static int bond_option_ad_actor_sys_prio_set(struct bonding *bond,
        return 0;
 }
 
+static int bond_option_actor_port_prio_set(struct bonding *bond,
+                                          const struct bond_opt_value *newval)
+{
+       struct slave *slave;
+
+       slave = bond_slave_get_rtnl(newval->slave_dev);
+       if (!slave) {
+               netdev_dbg(bond->dev, "%s called on NULL slave\n", __func__);
+               return -ENODEV;
+       }
+
+       netdev_dbg(newval->slave_dev, "Setting actor_port_prio to %llu\n",
+                  newval->value);
+
+       SLAVE_AD_INFO(slave)->port_priority = newval->value;
+       bond_3ad_update_ad_actor_settings(bond);
+
+       return 0;
+}
+
 static int bond_option_ad_actor_system_set(struct bonding *bond,
                                           const struct bond_opt_value *newval)
 {
index dba369a2cf27ef6258d029ded76299eb126e759f..e9188646e22e2aac824640b7a03ce2bbb27b588e 100644 (file)
@@ -274,6 +274,7 @@ struct ad_slave_info {
        struct port port;               /* 802.3ad port structure */
        struct bond_3ad_stats stats;
        u16 id;
+       u16 port_priority;
 };
 
 static inline const char *bond_3ad_churn_desc(churn_state_t state)
index 022b122a9fb61f74e8b6bdb31a478ca445926657..e6eedf23aea1a3adeb2f7f5bb7b6c176a689226f 100644 (file)
@@ -78,6 +78,7 @@ enum {
        BOND_OPT_PRIO,
        BOND_OPT_COUPLED_CONTROL,
        BOND_OPT_BROADCAST_NEIGH,
+       BOND_OPT_ACTOR_PORT_PRIO,
        BOND_OPT_LAST
 };
 
index 784ace3a519cd86dac3098df9c2f393e9827c158..45f56c9f95d90f8a8921b41f2c9b6355bd5058e8 100644 (file)
@@ -1564,6 +1564,7 @@ enum {
        IFLA_BOND_SLAVE_AD_ACTOR_OPER_PORT_STATE,
        IFLA_BOND_SLAVE_AD_PARTNER_OPER_PORT_STATE,
        IFLA_BOND_SLAVE_PRIO,
+       IFLA_BOND_SLAVE_ACTOR_PORT_PRIO,
        __IFLA_BOND_SLAVE_MAX,
 };