Commit 3121a1ef authored by Paolo Abeni's avatar Paolo Abeni
Browse files

Merge branch 'bonding-fix-incorrect-mac-address-setting'

Hangbin Liu says:

====================
bonding: fix incorrect mac address setting

The mac address on backup slave should be convert from Solicited-Node
Multicast address, not from bonding unicast target address.
====================

Link: https://patch.msgid.link/20250306023923.38777-1-liuhangbin@gmail.com


Signed-off-by: default avatarPaolo Abeni <pabeni@redhat.com>
parents f5d83cf0 9318dc23
Loading
Loading
Loading
Loading
+47 −8
Original line number Diff line number Diff line
@@ -1242,10 +1242,28 @@ static bool slave_can_set_ns_maddr(const struct bonding *bond, struct slave *sla
	       slave->dev->flags & IFF_MULTICAST;
}

/**
 * slave_set_ns_maddrs - add/del all NS mac addresses for slave
 * @bond: bond device
 * @slave: slave device
 * @add: add or remove all the NS mac addresses
 *
 * This function tries to add or delete all the NS mac addresses on the slave
 *
 * Note, the IPv6 NS target address is the unicast address in Neighbor
 * Solicitation (NS) message. The dest address of NS message should be
 * solicited-node multicast address of the target. The dest mac of NS message
 * is converted from the solicited-node multicast address.
 *
 * This function is called when
 *   * arp_validate changes
 *   * enslaving, releasing new slaves
 */
static void slave_set_ns_maddrs(struct bonding *bond, struct slave *slave, bool add)
{
	struct in6_addr *targets = bond->params.ns_targets;
	char slot_maddr[MAX_ADDR_LEN];
	struct in6_addr mcaddr;
	int i;

	if (!slave_can_set_ns_maddr(bond, slave))
@@ -1255,7 +1273,8 @@ static void slave_set_ns_maddrs(struct bonding *bond, struct slave *slave, bool
		if (ipv6_addr_any(&targets[i]))
			break;

		if (!ndisc_mc_map(&targets[i], slot_maddr, slave->dev, 0)) {
		addrconf_addr_solict_mult(&targets[i], &mcaddr);
		if (!ndisc_mc_map(&mcaddr, slot_maddr, slave->dev, 0)) {
			if (add)
				dev_mc_add(slave->dev, slot_maddr);
			else
@@ -1278,23 +1297,43 @@ void bond_slave_ns_maddrs_del(struct bonding *bond, struct slave *slave)
	slave_set_ns_maddrs(bond, slave, false);
}

/**
 * slave_set_ns_maddr - set new NS mac address for slave
 * @bond: bond device
 * @slave: slave device
 * @target: the new IPv6 target
 * @slot: the old IPv6 target in the slot
 *
 * This function tries to replace the old mac address to new one on the slave.
 *
 * Note, the target/slot IPv6 address is the unicast address in Neighbor
 * Solicitation (NS) message. The dest address of NS message should be
 * solicited-node multicast address of the target. The dest mac of NS message
 * is converted from the solicited-node multicast address.
 *
 * This function is called when
 *   * An IPv6 NS target is added or removed.
 */
static void slave_set_ns_maddr(struct bonding *bond, struct slave *slave,
			       struct in6_addr *target, struct in6_addr *slot)
{
	char target_maddr[MAX_ADDR_LEN], slot_maddr[MAX_ADDR_LEN];
	char mac_addr[MAX_ADDR_LEN];
	struct in6_addr mcast_addr;

	if (!bond->params.arp_validate || !slave_can_set_ns_maddr(bond, slave))
		return;

	/* remove the previous maddr from slave */
	/* remove the previous mac addr from slave */
	addrconf_addr_solict_mult(slot, &mcast_addr);
	if (!ipv6_addr_any(slot) &&
	    !ndisc_mc_map(slot, slot_maddr, slave->dev, 0))
		dev_mc_del(slave->dev, slot_maddr);
	    !ndisc_mc_map(&mcast_addr, mac_addr, slave->dev, 0))
		dev_mc_del(slave->dev, mac_addr);

	/* add new maddr on slave if target is set */
	/* add new mac addr on slave if target is set */
	addrconf_addr_solict_mult(target, &mcast_addr);
	if (!ipv6_addr_any(target) &&
	    !ndisc_mc_map(target, target_maddr, slave->dev, 0))
		dev_mc_add(slave->dev, target_maddr);
	    !ndisc_mc_map(&mcast_addr, mac_addr, slave->dev, 0))
		dev_mc_add(slave->dev, mac_addr);
}

static void _bond_options_ns_ip6_target_set(struct bonding *bond, int slot,
+2 −2
Original line number Diff line number Diff line
@@ -11,8 +11,8 @@ ALL_TESTS="

lib_dir=$(dirname "$0")
source ${lib_dir}/bond_topo_3d1c.sh
c_maddr="33:33:00:00:00:10"
g_maddr="33:33:00:00:02:54"
c_maddr="33:33:ff:00:00:10"
g_maddr="33:33:ff:00:02:54"

skip_prio()
{