All of lore.kernel.org
 help / color / mirror / Atom feed
From: Hangbin Liu <liuhangbin@gmail.com>
To: netdev@vger.kernel.org
Cc: Jay Vosburgh <jv@jvosburgh.net>,
	Andrew Lunn <andrew+netdev@lunn.ch>,
	"David S. Miller" <davem@davemloft.net>,
	Eric Dumazet <edumazet@google.com>,
	Jakub Kicinski <kuba@kernel.org>, Paolo Abeni <pabeni@redhat.com>,
	Nikolay Aleksandrov <razor@blackwall.org>,
	Simon Horman <horms@kernel.org>,
	linux-kernel@vger.kernel.org, Hangbin Liu <liuhangbin@gmail.com>,
	Liang Li <liali@redhat.com>
Subject: [PATCHv2 net] bonding: fix multicast MAC address synchronization
Date: Tue,  5 Aug 2025 08:09:36 +0000	[thread overview]
Message-ID: <20250805080936.39830-1-liuhangbin@gmail.com> (raw)

There is a corner case where the NS (Neighbor Solicitation) target is set to
an invalid or unreachable address. In such cases, all the slave links are
marked as down and set to *backup*. This causes the bond to add multicast MAC
addresses to all slaves. The ARP monitor then cycles through each slave to
probe them, temporarily marking as *active*.

Later, if the NS target is changed or cleared during this probe cycle, the
*active* slave will fail to remove its NS multicast address because
bond_slave_ns_maddrs_del() only removes addresses from backup slaves.
This leaves stale multicast MACs on the interface.

To fix this, we move the NS multicast MAC address handling into
bond_set_slave_state(), so every slave state transition consistently
adds/removes NS multicast addresses as needed.

We also ensure this logic is only active when arp_interval is configured,
to prevent misconfiguration or accidental behavior in unsupported modes.

Note: Cleanup in __bond_release_one() is retained to remove addresses
when the slave is unbound from the bond.

Fixes: 8eb36164d1a6 ("bonding: add ns target multicast address to slave device")
Reported-by: Liang Li <liali@redhat.com>
Signed-off-by: Hangbin Liu <liuhangbin@gmail.com>
---
v2:
1) Make sure arp_interval is set befer setting slave mac address.
2) add comment about why we need to set slave->backup between two if blocks
3) update commit description
---
 drivers/net/bonding/bond_main.c    |  9 ---------
 drivers/net/bonding/bond_options.c |  1 +
 include/net/bonding.h              | 17 +++++++++++++++++
 3 files changed, 18 insertions(+), 9 deletions(-)

diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index 257333c88710..283615d8a3fd 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -1003,8 +1003,6 @@ static void bond_hw_addr_swap(struct bonding *bond, struct slave *new_active,
 
 		if (bond->dev->flags & IFF_UP)
 			bond_hw_addr_flush(bond->dev, old_active->dev);
-
-		bond_slave_ns_maddrs_add(bond, old_active);
 	}
 
 	if (new_active) {
@@ -1021,8 +1019,6 @@ static void bond_hw_addr_swap(struct bonding *bond, struct slave *new_active,
 			dev_mc_sync(new_active->dev, bond->dev);
 			netif_addr_unlock_bh(bond->dev);
 		}
-
-		bond_slave_ns_maddrs_del(bond, new_active);
 	}
 }
 
@@ -2373,11 +2369,6 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev,
 	bond_compute_features(bond);
 	bond_set_carrier(bond);
 
-	/* Needs to be called before bond_select_active_slave(), which will
-	 * remove the maddrs if the slave is selected as active slave.
-	 */
-	bond_slave_ns_maddrs_add(bond, new_slave);
-
 	if (bond_uses_primary(bond)) {
 		block_netpoll_tx();
 		bond_select_active_slave(bond);
diff --git a/drivers/net/bonding/bond_options.c b/drivers/net/bonding/bond_options.c
index 1d639a3be6ba..f54386982198 100644
--- a/drivers/net/bonding/bond_options.c
+++ b/drivers/net/bonding/bond_options.c
@@ -1264,6 +1264,7 @@ static int bond_option_arp_ip_targets_set(struct bonding *bond,
 static bool slave_can_set_ns_maddr(const struct bonding *bond, struct slave *slave)
 {
 	return BOND_MODE(bond) == BOND_MODE_ACTIVEBACKUP &&
+	       bond->params.arp_interval &&
 	       !bond_is_active_slave(slave) &&
 	       slave->dev->flags & IFF_MULTICAST;
 }
diff --git a/include/net/bonding.h b/include/net/bonding.h
index e06f0d63b2c1..951d752a5301 100644
--- a/include/net/bonding.h
+++ b/include/net/bonding.h
@@ -388,7 +388,24 @@ static inline void bond_set_slave_state(struct slave *slave,
 	if (slave->backup == slave_state)
 		return;
 
+	/*
+	 * The slave->backup assignment must occur between the two if blocks.
+	 * This is because bond_slave_ns_maddrs_{add,del} only operate on
+	 * backup slaves:
+	 *
+	 * - If the slave is transitioning to active, we must call
+	 *   bond_slave_ns_maddrs_del() *before* updating the backup flag.
+	 * - If transitioning to backup, we must call
+	 *   bond_slave_ns_maddrs_add() *after* setting the flag.
+	 */
+	if (slave_state == BOND_STATE_ACTIVE)
+		bond_slave_ns_maddrs_del(slave->bond, slave);
+
 	slave->backup = slave_state;
+
+	if (slave_state == BOND_STATE_BACKUP)
+		bond_slave_ns_maddrs_add(slave->bond, slave);
+
 	if (notify) {
 		bond_lower_state_changed(slave);
 		bond_queue_slave_event(slave);
-- 
2.46.0


             reply	other threads:[~2025-08-05  8:09 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-08-05  8:09 Hangbin Liu [this message]
2025-08-12  8:42 ` [PATCHv2 net] bonding: fix multicast MAC address synchronization Paolo Abeni
2025-08-13  4:04   ` Hangbin Liu
2025-09-09  3:42     ` Hangbin Liu
2026-03-11  2:41       ` Hangbin Liu

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20250805080936.39830-1-liuhangbin@gmail.com \
    --to=liuhangbin@gmail.com \
    --cc=andrew+netdev@lunn.ch \
    --cc=davem@davemloft.net \
    --cc=edumazet@google.com \
    --cc=horms@kernel.org \
    --cc=jv@jvosburgh.net \
    --cc=kuba@kernel.org \
    --cc=liali@redhat.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=netdev@vger.kernel.org \
    --cc=pabeni@redhat.com \
    --cc=razor@blackwall.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.