예제 #1
0
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;
}
예제 #2
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;
}
예제 #3
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;
	}
예제 #4
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;
	}