From b1759462922450aad50e4ccdbb0450f4c3674204 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Tue, 14 Oct 2025 11:21:21 +0200 Subject: [PATCH] fix --- drivers/net/bonding/bond_main.c | 62 +++++++++++++++++++-------------- 1 file changed, 35 insertions(+), 27 deletions(-) diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 57be04f6cb11..e90ab5d0b718 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -5384,6 +5384,31 @@ static netdev_tx_t bond_3ad_xor_xmit(struct sk_buff *skb, return bond_tx_drop(dev, skb); } +static void loop(struct net_device *bond_dev, struct slave *slave, struct sk_buff *skb, + bool *skb_used, bool *xmit_suc) +{ + struct bonding *bond = netdev_priv(bond_dev); + struct sk_buff *skb2; + + if (!(bond_slave_is_up(slave) && slave->link == BOND_LINK_UP)) + return; + + if (bond_is_last_slave(bond, slave)) { + skb2 = skb; + *skb_used = true; + } else { + skb2 = skb_clone(skb, GFP_ATOMIC); + if (!skb2) { + net_err_ratelimited("%s: Error: %s: skb_clone() failed\n", + bond_dev->name, __func__); + return; + } + } + + if (bond_dev_queue_xmit(bond, skb2, slave->dev) == NETDEV_TX_OK) + *xmit_suc = true; +} + /* in broadcast mode, we send everything to all or usable slave interfaces. * under rcu_read_lock when this function is called. */ @@ -5395,35 +5420,18 @@ static netdev_tx_t bond_xmit_broadcast(struct sk_buff *skb, struct bond_up_slave *slaves; bool xmit_suc = false; bool skb_used = false; - int slaves_count, i; - - if (all_slaves) - slaves = rcu_dereference(bond->all_slaves); - else - slaves = rcu_dereference(bond->usable_slaves); - slaves_count = slaves ? READ_ONCE(slaves->count) : 0; - for (i = 0; i < slaves_count; i++) { - struct slave *slave = slaves->arr[i]; - struct sk_buff *skb2; - - if (!(bond_slave_is_up(slave) && slave->link == BOND_LINK_UP)) - continue; - - if (bond_is_last_slave(bond, slave)) { - skb2 = skb; - skb_used = true; - } else { - skb2 = skb_clone(skb, GFP_ATOMIC); - if (!skb2) { - net_err_ratelimited("%s: Error: %s: skb_clone() failed\n", - bond_dev->name, __func__); - continue; - } + if (all_slaves) { + struct slave *slave = NULL; + struct list_head *iter; + bond_for_each_slave_rcu(bond, slave, iter) { + loop(bond_dev, slave, skb, &skb_used, &xmit_suc); } - - if (bond_dev_queue_xmit(bond, skb2, slave->dev) == NETDEV_TX_OK) - xmit_suc = true; + } else { + slaves = rcu_dereference(bond->usable_slaves); + int slaves_count = slaves ? READ_ONCE(slaves->count) : 0; + for (int i = 0; i < slaves_count; i++) + loop(bond_dev, slaves->arr[i], skb, &skb_used, &xmit_suc); } if (!skb_used) -- 2.51.0