]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
bonding: fix ns validation on backup slaves
authorHangbin Liu <liuhangbin@gmail.com>
Thu, 6 Apr 2023 08:23:50 +0000 (16:23 +0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 20 Apr 2023 10:35:08 +0000 (12:35 +0200)
[ Upstream commit 4598380f9c548aa161eb4e990a1583f0a7d1e0d7 ]

When arp_validate is set to 2, 3, or 6, validation is performed for
backup slaves as well. As stated in the bond documentation, validation
involves checking the broadcast ARP request sent out via the active
slave. This helps determine which slaves are more likely to function in
the event of an active slave failure.

However, when the target is an IPv6 address, the NS message sent from
the active interface is not checked on backup slaves. Additionally,
based on the bond_arp_rcv() rule b, we must reverse the saddr and daddr
when checking the NS message.

Note that when checking the NS message, the destination address is a
multicast address. Therefore, we must convert the target address to
solicited multicast in the bond_get_targets_ip6() function.

Prior to the fix, the backup slaves had a mii status of "down", but
after the fix, all of the slaves' mii status was updated to "UP".

Fixes: 4e24be018eb9 ("bonding: add new parameter ns_targets")
Reviewed-by: Jonathan Toppins <jtoppins@redhat.com>
Acked-by: Jay Vosburgh <jay.vosburgh@canonical.com>
Signed-off-by: Hangbin Liu <liuhangbin@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Sasha Levin <sashal@kernel.org>
drivers/net/bonding/bond_main.c
include/net/bonding.h

index 45d3cb557de73a1b96f0a1d9d91bf99a6ca44267..9f6824a6537bce11af73790cf7a14069053aa8f1 100644 (file)
@@ -3266,7 +3266,8 @@ static int bond_na_rcv(const struct sk_buff *skb, struct bonding *bond,
 
        combined = skb_header_pointer(skb, 0, sizeof(_combined), &_combined);
        if (!combined || combined->ip6.nexthdr != NEXTHDR_ICMP ||
-           combined->icmp6.icmp6_type != NDISC_NEIGHBOUR_ADVERTISEMENT)
+           (combined->icmp6.icmp6_type != NDISC_NEIGHBOUR_SOLICITATION &&
+            combined->icmp6.icmp6_type != NDISC_NEIGHBOUR_ADVERTISEMENT))
                goto out;
 
        saddr = &combined->ip6.saddr;
@@ -3288,7 +3289,7 @@ static int bond_na_rcv(const struct sk_buff *skb, struct bonding *bond,
        else if (curr_active_slave &&
                 time_after(slave_last_rx(bond, curr_active_slave),
                            curr_active_slave->last_link_up))
-               bond_validate_na(bond, slave, saddr, daddr);
+               bond_validate_na(bond, slave, daddr, saddr);
        else if (curr_arp_slave &&
                 bond_time_in_interval(bond, slave_last_tx(curr_arp_slave), 1))
                bond_validate_na(bond, slave, saddr, daddr);
index e999f851738bd68b88ffb82daa6960aa5068c229..768348008d0c9c8f98acefe5ead7f24784c9f218 100644 (file)
@@ -765,13 +765,17 @@ static inline int bond_get_targets_ip(__be32 *targets, __be32 ip)
 #if IS_ENABLED(CONFIG_IPV6)
 static inline int bond_get_targets_ip6(struct in6_addr *targets, struct in6_addr *ip)
 {
+       struct in6_addr mcaddr;
        int i;
 
-       for (i = 0; i < BOND_MAX_NS_TARGETS; i++)
-               if (ipv6_addr_equal(&targets[i], ip))
+       for (i = 0; i < BOND_MAX_NS_TARGETS; i++) {
+               addrconf_addr_solict_mult(&targets[i], &mcaddr);
+               if ((ipv6_addr_equal(&targets[i], ip)) ||
+                   (ipv6_addr_equal(&mcaddr, ip)))
                        return i;
                else if (ipv6_addr_any(&targets[i]))
                        break;
+       }
 
        return -1;
 }