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) {
                        dev_mc_sync(new_active->dev, bond->dev);
                        netif_addr_unlock_bh(bond->dev);
                }
+
+               bond_slave_ns_maddrs_del(bond, new_active);
        }
 }
 
        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);
        if (bond_mode_can_use_xmit_hash(bond))
                bond_update_slave_arr(bond, NULL);
 
-
        if (!slave_dev->netdev_ops->ndo_bpf ||
            !slave_dev->netdev_ops->ndo_xdp_xmit) {
                if (bond->xdp_prog) {
        if (oldcurrent == slave)
                bond_change_active_slave(bond, NULL);
 
+       /* Must be called after bond_change_active_slave () as the slave
+        * might change from an active slave to a backup slave. Then it is
+        * necessary to clear the maddrs on the backup slave.
+        */
+       bond_slave_ns_maddrs_del(bond, slave);
+
        if (bond_is_lb(bond)) {
                /* Must be called only after the slave has been
                 * detached from the list and the curr_active_slave
 
 #include <linux/sched/signal.h>
 
 #include <net/bonding.h>
+#include <net/ndisc.h>
 
 static int bond_option_active_slave_set(struct bonding *bond,
                                        const struct bond_opt_value *newval);
 }
 
 #if IS_ENABLED(CONFIG_IPV6)
+static bool slave_can_set_ns_maddr(const struct bonding *bond, struct slave *slave)
+{
+       return BOND_MODE(bond) == BOND_MODE_ACTIVEBACKUP &&
+              !bond_is_active_slave(slave) &&
+              slave->dev->flags & IFF_MULTICAST;
+}
+
+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];
+       int i;
+
+       if (!slave_can_set_ns_maddr(bond, slave))
+               return;
+
+       for (i = 0; i < BOND_MAX_NS_TARGETS; i++) {
+               if (ipv6_addr_any(&targets[i]))
+                       break;
+
+               if (!ndisc_mc_map(&targets[i], slot_maddr, slave->dev, 0)) {
+                       if (add)
+                               dev_mc_add(slave->dev, slot_maddr);
+                       else
+                               dev_mc_del(slave->dev, slot_maddr);
+               }
+       }
+}
+
+void bond_slave_ns_maddrs_add(struct bonding *bond, struct slave *slave)
+{
+       if (!bond->params.arp_validate)
+               return;
+       slave_set_ns_maddrs(bond, slave, true);
+}
+
+void bond_slave_ns_maddrs_del(struct bonding *bond, struct slave *slave)
+{
+       if (!bond->params.arp_validate)
+               return;
+       slave_set_ns_maddrs(bond, slave, false);
+}
+
+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];
+
+       if (!bond->params.arp_validate || !slave_can_set_ns_maddr(bond, slave))
+               return;
+
+       /* remove the previous maddr from slave */
+       if (!ipv6_addr_any(slot) &&
+           !ndisc_mc_map(slot, slot_maddr, slave->dev, 0))
+               dev_mc_del(slave->dev, slot_maddr);
+
+       /* add new maddr on slave if target is set */
+       if (!ipv6_addr_any(target) &&
+           !ndisc_mc_map(target, target_maddr, slave->dev, 0))
+               dev_mc_add(slave->dev, target_maddr);
+}
+
 static void _bond_options_ns_ip6_target_set(struct bonding *bond, int slot,
                                            struct in6_addr *target,
                                            unsigned long last_rx)
        struct slave *slave;
 
        if (slot >= 0 && slot < BOND_MAX_NS_TARGETS) {
-               bond_for_each_slave(bond, slave, iter)
+               bond_for_each_slave(bond, slave, iter) {
                        slave->target_last_arp_rx[slot] = last_rx;
+                       slave_set_ns_maddr(bond, slave, target, &targets[slot]);
+               }
                targets[slot] = *target;
        }
 }
 {
        return -EPERM;
 }
+
+static void slave_set_ns_maddrs(struct bonding *bond, struct slave *slave, bool add) {}
+
+void bond_slave_ns_maddrs_add(struct bonding *bond, struct slave *slave) {}
+
+void bond_slave_ns_maddrs_del(struct bonding *bond, struct slave *slave) {}
 #endif
 
 static int bond_option_arp_validate_set(struct bonding *bond,
                                        const struct bond_opt_value *newval)
 {
+       bool changed = !!bond->params.arp_validate != !!newval->value;
+       struct list_head *iter;
+       struct slave *slave;
+
        netdev_dbg(bond->dev, "Setting arp_validate to %s (%llu)\n",
                   newval->string, newval->value);
        bond->params.arp_validate = newval->value;
 
+       if (changed) {
+               bond_for_each_slave(bond, slave, iter)
+                       slave_set_ns_maddrs(bond, slave, !!bond->params.arp_validate);
+       }
+
        return 0;
 }