|
@@ -591,7 +591,7 @@ static ssize_t bonding_store_arp_targets(struct device *d,
|
|
|
const char *buf, size_t count)
|
|
|
{
|
|
|
__be32 newtarget;
|
|
|
- int i = 0, done = 0, ret = count;
|
|
|
+ int i = 0, ret = -EINVAL;
|
|
|
struct bonding *bond = to_bond(d);
|
|
|
__be32 *targets;
|
|
|
|
|
@@ -602,57 +602,44 @@ static ssize_t bonding_store_arp_targets(struct device *d,
|
|
|
if ((newtarget == 0) || (newtarget == htonl(INADDR_BROADCAST))) {
|
|
|
pr_err("%s: invalid ARP target %pI4 specified for addition\n",
|
|
|
bond->dev->name, &newtarget);
|
|
|
- ret = -EINVAL;
|
|
|
goto out;
|
|
|
}
|
|
|
- /* look for an empty slot to put the target in, and check for dupes */
|
|
|
- for (i = 0; (i < BOND_MAX_ARP_TARGETS) && !done; i++) {
|
|
|
- if (targets[i] == newtarget) { /* duplicate */
|
|
|
- pr_err("%s: ARP target %pI4 is already present\n",
|
|
|
- bond->dev->name, &newtarget);
|
|
|
- ret = -EINVAL;
|
|
|
- goto out;
|
|
|
- }
|
|
|
- if (targets[i] == 0) {
|
|
|
- pr_info("%s: adding ARP target %pI4.\n",
|
|
|
- bond->dev->name, &newtarget);
|
|
|
- done = 1;
|
|
|
- targets[i] = newtarget;
|
|
|
- }
|
|
|
+
|
|
|
+ if (bond_get_targets_ip(targets, newtarget) != -1) { /* dup */
|
|
|
+ pr_err("%s: ARP target %pI4 is already present\n",
|
|
|
+ bond->dev->name, &newtarget);
|
|
|
+ goto out;
|
|
|
}
|
|
|
- if (!done) {
|
|
|
+
|
|
|
+ i = bond_get_targets_ip(targets, 0); /* first free slot */
|
|
|
+ if (i == -1) {
|
|
|
pr_err("%s: ARP target table is full!\n",
|
|
|
bond->dev->name);
|
|
|
- ret = -EINVAL;
|
|
|
goto out;
|
|
|
}
|
|
|
|
|
|
+ pr_info("%s: adding ARP target %pI4.\n", bond->dev->name,
|
|
|
+ &newtarget);
|
|
|
+ targets[i] = newtarget;
|
|
|
} else if (buf[0] == '-') {
|
|
|
if ((newtarget == 0) || (newtarget == htonl(INADDR_BROADCAST))) {
|
|
|
pr_err("%s: invalid ARP target %pI4 specified for removal\n",
|
|
|
bond->dev->name, &newtarget);
|
|
|
- ret = -EINVAL;
|
|
|
goto out;
|
|
|
}
|
|
|
|
|
|
- for (i = 0; (i < BOND_MAX_ARP_TARGETS) && !done; i++) {
|
|
|
- if (targets[i] == newtarget) {
|
|
|
- int j;
|
|
|
- pr_info("%s: removing ARP target %pI4.\n",
|
|
|
- bond->dev->name, &newtarget);
|
|
|
- for (j = i; (j < (BOND_MAX_ARP_TARGETS-1)) && targets[j+1]; j++)
|
|
|
- targets[j] = targets[j+1];
|
|
|
-
|
|
|
- targets[j] = 0;
|
|
|
- done = 1;
|
|
|
- }
|
|
|
- }
|
|
|
- if (!done) {
|
|
|
+ i = bond_get_targets_ip(targets, newtarget);
|
|
|
+ if (i == -1) {
|
|
|
pr_info("%s: unable to remove nonexistent ARP target %pI4.\n",
|
|
|
bond->dev->name, &newtarget);
|
|
|
- ret = -EINVAL;
|
|
|
goto out;
|
|
|
}
|
|
|
+
|
|
|
+ pr_info("%s: removing ARP target %pI4.\n", bond->dev->name,
|
|
|
+ &newtarget);
|
|
|
+ for (; (i < BOND_MAX_ARP_TARGETS-1) && targets[i+1]; i++)
|
|
|
+ targets[i] = targets[i+1];
|
|
|
+ targets[i] = 0;
|
|
|
} else {
|
|
|
pr_err("no command found in arp_ip_targets file for bond %s. Use +<addr> or -<addr>.\n",
|
|
|
bond->dev->name);
|
|
@@ -660,6 +647,7 @@ static ssize_t bonding_store_arp_targets(struct device *d,
|
|
|
goto out;
|
|
|
}
|
|
|
|
|
|
+ ret = count;
|
|
|
out:
|
|
|
return ret;
|
|
|
}
|