static int _bond_option_arp_ip_target_add(struct bonding *bond, __be32 target) { __be32 *targets = bond->params.arp_targets; int ind; if (!bond_is_ip_target_ok(target)) { netdev_err(bond->dev, "invalid ARP target %pI4 specified for addition\n", &target); return -EINVAL; } if (bond_get_targets_ip(targets, target) != -1) { /* dup */ netdev_err(bond->dev, "ARP target %pI4 is already present\n", &target); return -EINVAL; } ind = bond_get_targets_ip(targets, 0); /* first free slot */ if (ind == -1) { netdev_err(bond->dev, "ARP target table is full!\n"); return -EINVAL; } netdev_dbg(bond->dev, "Adding ARP target %pI4\n", &target); _bond_options_arp_ip_target_set(bond, ind, target, jiffies); return 0; }
static int _bond_option_arp_ip_target_add(struct bonding *bond, __be32 target) { __be32 *targets = bond->params.arp_targets; int ind; if (IS_IP_TARGET_UNUSABLE_ADDRESS(target)) { pr_err("%s: invalid ARP target %pI4 specified for addition\n", bond->dev->name, &target); return -EINVAL; } if (bond_get_targets_ip(targets, target) != -1) { /* dup */ pr_err("%s: ARP target %pI4 is already present\n", bond->dev->name, &target); return -EINVAL; } ind = bond_get_targets_ip(targets, 0); /* first free slot */ if (ind == -1) { pr_err("%s: ARP target table is full!\n", bond->dev->name); return -EINVAL; } pr_info("%s: adding ARP target %pI4.\n", bond->dev->name, &target); _bond_options_arp_ip_target_set(bond, ind, target, jiffies); return 0; }
static int bond_option_arp_ip_target_rem(struct bonding *bond, __be32 target) { __be32 *targets = bond->params.arp_targets; struct list_head *iter; struct slave *slave; unsigned long *targets_rx; int ind, i; if (!bond_is_ip_target_ok(target)) { netdev_err(bond->dev, "invalid ARP target %pI4 specified for removal\n", &target); return -EINVAL; } ind = bond_get_targets_ip(targets, target); if (ind == -1) { netdev_err(bond->dev, "unable to remove nonexistent ARP target %pI4\n", &target); return -EINVAL; } if (ind == 0 && !targets[1] && bond->params.arp_interval) netdev_warn(bond->dev, "Removing last arp target with arp_interval on\n"); netdev_dbg(bond->dev, "Removing ARP target %pI4\n", &target); bond_for_each_slave(bond, slave, iter) { targets_rx = slave->target_last_arp_rx; for (i = ind; (i < BOND_MAX_ARP_TARGETS-1) && targets[i+1]; i++) targets_rx[i] = targets_rx[i+1]; targets_rx[i] = 0; }
int bond_option_arp_ip_target_rem(struct bonding *bond, __be32 target) { __be32 *targets = bond->params.arp_targets; struct list_head *iter; struct slave *slave; unsigned long *targets_rx; int ind, i; if (IS_IP_TARGET_UNUSABLE_ADDRESS(target)) { pr_err("%s: invalid ARP target %pI4 specified for removal\n", bond->dev->name, &target); return -EINVAL; } ind = bond_get_targets_ip(targets, target); if (ind == -1) { pr_err("%s: unable to remove nonexistent ARP target %pI4.\n", bond->dev->name, &target); return -EINVAL; } if (ind == 0 && !targets[1] && bond->params.arp_interval) pr_warn("%s: removing last arp target with arp_interval on\n", bond->dev->name); pr_info("%s: removing ARP target %pI4.\n", bond->dev->name, &target); /* not to race with bond_arp_rcv */ write_lock_bh(&bond->lock); bond_for_each_slave(bond, slave, iter) { targets_rx = slave->target_last_arp_rx; for (i = ind; (i < BOND_MAX_ARP_TARGETS-1) && targets[i+1]; i++) targets_rx[i] = targets_rx[i+1]; targets_rx[i] = 0; }