struct device_attribute *attr,
const char *buffer, size_t count)
{
- char command[IFNAMSIZ + 1] = { 0, };
- char *ifname;
- int res, ret = count;
- struct net_device *dev;
struct bonding *bond = to_bond(d);
+ int ret;
- if (!rtnl_trylock())
- return restart_syscall();
-
- sscanf(buffer, "%16s", command); /* IFNAMSIZ*/
- ifname = command + 1;
- if ((strlen(command) <= 1) ||
- !dev_valid_name(ifname))
- goto err_no_cmd;
-
- dev = __dev_get_by_name(dev_net(bond->dev), ifname);
- if (!dev) {
- pr_info("%s: Interface %s does not exist!\n",
- bond->dev->name, ifname);
- ret = -ENODEV;
- goto out;
- }
-
- switch (command[0]) {
- case '+':
- pr_info("%s: Adding slave %s.\n", bond->dev->name, dev->name);
- res = bond_enslave(bond->dev, dev);
- break;
-
- case '-':
- pr_info("%s: Removing slave %s.\n", bond->dev->name, dev->name);
- res = bond_release(bond->dev, dev);
- break;
-
- default:
- goto err_no_cmd;
- }
-
- if (res)
- ret = res;
- goto out;
-
-err_no_cmd:
- pr_err("no command found in slaves file for bond %s. Use +ifname or -ifname.\n",
- bond->dev->name);
- ret = -EPERM;
+ ret = bond_opt_tryset_rtnl(bond, BOND_OPT_SLAVES, (char *)buffer);
+ if (!ret)
+ ret = count;
-out:
- rtnl_unlock();
return ret;
}
-
static DEVICE_ATTR(slaves, S_IRUGO | S_IWUSR, bonding_show_slaves,
bonding_store_slaves);
struct device_attribute *attr,
char *buf)
{
- int i, res = 0;
struct bonding *bond = to_bond(d);
+ int i, res = 0;
for (i = 0; i < BOND_MAX_ARP_TARGETS; i++) {
if (bond->params.arp_targets[i])
}
if (res)
buf[res-1] = '\n'; /* eat the leftover space */
+
return res;
}
const char *buf, size_t count)
{
struct bonding *bond = to_bond(d);
- __be32 target;
- int ret = -EPERM;
-
- if (!in4_pton(buf + 1, -1, (u8 *)&target, -1, NULL)) {
- pr_err("%s: invalid ARP target %pI4 specified\n",
- bond->dev->name, &target);
- return -EPERM;
- }
-
- if (!rtnl_trylock())
- return restart_syscall();
-
- if (buf[0] == '+')
- ret = bond_option_arp_ip_target_add(bond, target);
- else if (buf[0] == '-')
- ret = bond_option_arp_ip_target_rem(bond, target);
- else
- pr_err("no command found in arp_ip_targets file for bond %s. Use +<addr> or -<addr>.\n",
- bond->dev->name);
+ int ret;
+ ret = bond_opt_tryset_rtnl(bond, BOND_OPT_ARP_TARGETS, (char *)buf);
if (!ret)
ret = count;
- rtnl_unlock();
return ret;
}
static DEVICE_ATTR(arp_ip_target, S_IRUGO | S_IWUSR , bonding_show_arp_targets, bonding_store_arp_targets);
struct device_attribute *attr,
const char *buf, size_t count)
{
- int new_value, ret;
struct bonding *bond = to_bond(d);
+ int ret;
- if (sscanf(buf, "%d", &new_value) != 1) {
- pr_err("%s: no down delay value specified.\n", bond->dev->name);
- return -EINVAL;
- }
-
- if (!rtnl_trylock())
- return restart_syscall();
-
- ret = bond_option_downdelay_set(bond, new_value);
+ ret = bond_opt_tryset_rtnl(bond, BOND_OPT_DOWNDELAY, (char *)buf);
if (!ret)
ret = count;
- rtnl_unlock();
return ret;
}
static DEVICE_ATTR(downdelay, S_IRUGO | S_IWUSR,
struct device_attribute *attr,
const char *buf, size_t count)
{
- int new_value, ret;
struct bonding *bond = to_bond(d);
+ int ret;
- if (sscanf(buf, "%d", &new_value) != 1) {
- pr_err("%s: no up delay value specified.\n",
- bond->dev->name);
- return -EINVAL;
- }
-
- if (!rtnl_trylock())
- return restart_syscall();
-
- ret = bond_option_updelay_set(bond, new_value);
+ ret = bond_opt_tryset_rtnl(bond, BOND_OPT_UPDELAY, (char *)buf);
if (!ret)
ret = count;
- rtnl_unlock();
return ret;
}
static DEVICE_ATTR(updelay, S_IRUGO | S_IWUSR,
char *buf)
{
struct bonding *bond = to_bond(d);
+ struct bond_opt_value *val;
- return sprintf(buf, "%s %d\n",
- bond_lacp_tbl[bond->params.lacp_fast].modename,
- bond->params.lacp_fast);
+ val = bond_opt_get_val(BOND_OPT_LACP_RATE, bond->params.lacp_fast);
+
+ return sprintf(buf, "%s %d\n", val->string, bond->params.lacp_fast);
}
static ssize_t bonding_store_lacp(struct device *d,
const char *buf, size_t count)
{
struct bonding *bond = to_bond(d);
- int new_value, ret;
-
- new_value = bond_parse_parm(buf, bond_lacp_tbl);
- if (new_value < 0) {
- pr_err("%s: Ignoring invalid LACP rate value %.*s.\n",
- bond->dev->name, (int)strlen(buf) - 1, buf);
- return -EINVAL;
- }
-
- if (!rtnl_trylock())
- return restart_syscall();
+ int ret;
- ret = bond_option_lacp_rate_set(bond, new_value);
+ ret = bond_opt_tryset_rtnl(bond, BOND_OPT_LACP_RATE, (char *)buf);
if (!ret)
ret = count;
- rtnl_unlock();
return ret;
}
static DEVICE_ATTR(lacp_rate, S_IRUGO | S_IWUSR,
{
struct bonding *bond = to_bond(d);
int ret;
- unsigned int new_value;
-
- ret = kstrtouint(buf, 0, &new_value);
- if (ret < 0) {
- pr_err("%s: Ignoring invalid min links value %s.\n",
- bond->dev->name, buf);
- return ret;
- }
-
- if (!rtnl_trylock())
- return restart_syscall();
- ret = bond_option_min_links_set(bond, new_value);
+ ret = bond_opt_tryset_rtnl(bond, BOND_OPT_MINLINKS, (char *)buf);
if (!ret)
ret = count;
- rtnl_unlock();
return ret;
}
static DEVICE_ATTR(min_links, S_IRUGO | S_IWUSR,
char *buf)
{
struct bonding *bond = to_bond(d);
+ struct bond_opt_value *val;
- return sprintf(buf, "%s %d\n",
- ad_select_tbl[bond->params.ad_select].modename,
- bond->params.ad_select);
+ val = bond_opt_get_val(BOND_OPT_AD_SELECT, bond->params.ad_select);
+
+ return sprintf(buf, "%s %d\n", val->string, bond->params.ad_select);
}
struct device_attribute *attr,
const char *buf, size_t count)
{
- int new_value, ret;
struct bonding *bond = to_bond(d);
+ int ret;
- new_value = bond_parse_parm(buf, ad_select_tbl);
- if (new_value < 0) {
- pr_err("%s: Ignoring invalid ad_select value %.*s.\n",
- bond->dev->name, (int)strlen(buf) - 1, buf);
- return -EINVAL;
- }
-
- if (!rtnl_trylock())
- return restart_syscall();
-
- ret = bond_option_ad_select_set(bond, new_value);
+ ret = bond_opt_tryset_rtnl(bond, BOND_OPT_AD_SELECT, (char *)buf);
if (!ret)
ret = count;
- rtnl_unlock();
return ret;
}
static DEVICE_ATTR(ad_select, S_IRUGO | S_IWUSR,
const char *buf, size_t count)
{
struct bonding *bond = to_bond(d);
- u8 new_value;
int ret;
- ret = kstrtou8(buf, 10, &new_value);
- if (ret) {
- pr_err("%s: invalid value %s specified.\n",
- bond->dev->name, buf);
- return ret;
- }
-
- if (!rtnl_trylock())
- return restart_syscall();
-
- ret = bond_option_num_peer_notif_set(bond, new_value);
+ ret = bond_opt_tryset_rtnl(bond, BOND_OPT_NUM_PEER_NOTIF, (char *)buf);
if (!ret)
ret = count;
- rtnl_unlock();
return ret;
}
static DEVICE_ATTR(num_grat_arp, S_IRUGO | S_IWUSR,
struct device_attribute *attr,
const char *buf, size_t count)
{
- int new_value, ret;
struct bonding *bond = to_bond(d);
+ int ret;
- if (sscanf(buf, "%d", &new_value) != 1) {
- pr_err("%s: no miimon value specified.\n",
- bond->dev->name);
- return -EINVAL;
- }
-
- if (!rtnl_trylock())
- return restart_syscall();
-
- ret = bond_option_miimon_set(bond, new_value);
+ ret = bond_opt_tryset_rtnl(bond, BOND_OPT_MIIMON, (char *)buf);
if (!ret)
ret = count;
- rtnl_unlock();
return ret;
}
static DEVICE_ATTR(miimon, S_IRUGO | S_IWUSR,
const char *buf, size_t count)
{
struct bonding *bond = to_bond(d);
- char ifname[IFNAMSIZ];
int ret;
- sscanf(buf, "%15s", ifname); /* IFNAMSIZ */
- if (ifname[0] == '\n')
- ifname[0] = '\0';
-
- if (!rtnl_trylock())
- return restart_syscall();
-
- ret = bond_option_primary_set(bond, ifname);
+ ret = bond_opt_tryset_rtnl(bond, BOND_OPT_PRIMARY, (char *)buf);
if (!ret)
ret = count;
- rtnl_unlock();
return ret;
}
static DEVICE_ATTR(primary, S_IRUGO | S_IWUSR,
char *buf)
{
struct bonding *bond = to_bond(d);
+ struct bond_opt_value *val;
+
+ val = bond_opt_get_val(BOND_OPT_PRIMARY_RESELECT,
+ bond->params.primary_reselect);
return sprintf(buf, "%s %d\n",
- pri_reselect_tbl[bond->params.primary_reselect].modename,
- bond->params.primary_reselect);
+ val->string, bond->params.primary_reselect);
}
static ssize_t bonding_store_primary_reselect(struct device *d,
struct device_attribute *attr,
const char *buf, size_t count)
{
- int new_value, ret;
struct bonding *bond = to_bond(d);
+ int ret;
- new_value = bond_parse_parm(buf, pri_reselect_tbl);
- if (new_value < 0) {
- pr_err("%s: Ignoring invalid primary_reselect value %.*s.\n",
- bond->dev->name,
- (int) strlen(buf) - 1, buf);
- return -EINVAL;
- }
-
- if (!rtnl_trylock())
- return restart_syscall();
-
- ret = bond_option_primary_reselect_set(bond, new_value);
+ ret = bond_opt_tryset_rtnl(bond, BOND_OPT_PRIMARY_RESELECT,
+ (char *)buf);
if (!ret)
ret = count;
- rtnl_unlock();
return ret;
}
static DEVICE_ATTR(primary_reselect, S_IRUGO | S_IWUSR,
struct device_attribute *attr,
const char *buf, size_t count)
{
- int new_value, ret;
struct bonding *bond = to_bond(d);
+ int ret;
- if (sscanf(buf, "%d", &new_value) != 1) {
- pr_err("%s: no use_carrier value specified.\n",
- bond->dev->name);
- return -EINVAL;
- }
-
- if (!rtnl_trylock())
- return restart_syscall();
-
- ret = bond_option_use_carrier_set(bond, new_value);
+ ret = bond_opt_tryset_rtnl(bond, BOND_OPT_USE_CARRIER, (char *)buf);
if (!ret)
ret = count;
- rtnl_unlock();
return ret;
}
static DEVICE_ATTR(use_carrier, S_IRUGO | S_IWUSR,
struct device_attribute *attr,
const char *buf, size_t count)
{
- int ret;
struct bonding *bond = to_bond(d);
- char ifname[IFNAMSIZ];
- struct net_device *dev;
-
- if (!rtnl_trylock())
- return restart_syscall();
-
- sscanf(buf, "%15s", ifname); /* IFNAMSIZ */
- if (!strlen(ifname) || buf[0] == '\n') {
- dev = NULL;
- } else {
- dev = __dev_get_by_name(dev_net(bond->dev), ifname);
- if (!dev) {
- ret = -ENODEV;
- goto out;
- }
- }
+ int ret;
- ret = bond_option_active_slave_set(bond, dev);
+ ret = bond_opt_tryset_rtnl(bond, BOND_OPT_ACTIVE_SLAVE, (char *)buf);
if (!ret)
ret = count;
- out:
- rtnl_unlock();
-
return ret;
-
}
static DEVICE_ATTR(active_slave, S_IRUGO | S_IWUSR,
bonding_show_active_slave, bonding_store_active_slave);
struct device_attribute *attr,
const char *buffer, size_t count)
{
- struct slave *slave, *update_slave;
struct bonding *bond = to_bond(d);
- struct list_head *iter;
- u16 qid;
- int ret = count;
- char *delim;
- struct net_device *sdev = NULL;
-
- if (!rtnl_trylock())
- return restart_syscall();
-
- /* delim will point to queue id if successful */
- delim = strchr(buffer, ':');
- if (!delim)
- goto err_no_cmd;
-
- /*
- * Terminate string that points to device name and bump it
- * up one, so we can read the queue id there.
- */
- *delim = '\0';
- if (sscanf(++delim, "%hd\n", &qid) != 1)
- goto err_no_cmd;
-
- /* Check buffer length, valid ifname and queue id */
- if (strlen(buffer) > IFNAMSIZ ||
- !dev_valid_name(buffer) ||
- qid > bond->dev->real_num_tx_queues)
- goto err_no_cmd;
-
- /* Get the pointer to that interface if it exists */
- sdev = __dev_get_by_name(dev_net(bond->dev), buffer);
- if (!sdev)
- goto err_no_cmd;
-
- /* Search for thes slave and check for duplicate qids */
- update_slave = NULL;
- bond_for_each_slave(bond, slave, iter) {
- if (sdev == slave->dev)
- /*
- * We don't need to check the matching
- * slave for dups, since we're overwriting it
- */
- update_slave = slave;
- else if (qid && qid == slave->queue_id) {
- goto err_no_cmd;
- }
- }
-
- if (!update_slave)
- goto err_no_cmd;
+ int ret;
- /* Actually set the qids for the slave */
- update_slave->queue_id = qid;
+ ret = bond_opt_tryset_rtnl(bond, BOND_OPT_QUEUE_ID, (char *)buffer);
+ if (!ret)
+ ret = count;
-out:
- rtnl_unlock();
return ret;
-
-err_no_cmd:
- pr_info("invalid input for queue_id set for %s.\n",
- bond->dev->name);
- ret = -EPERM;
- goto out;
}
-
static DEVICE_ATTR(queue_id, S_IRUGO | S_IWUSR, bonding_show_queue_id,
bonding_store_queue_id);
const char *buf, size_t count)
{
struct bonding *bond = to_bond(d);
- int new_value, ret;
-
- if (sscanf(buf, "%d", &new_value) != 1) {
- pr_err("%s: no all_slaves_active value specified.\n",
- bond->dev->name);
- return -EINVAL;
- }
-
- if (!rtnl_trylock())
- return restart_syscall();
+ int ret;
- ret = bond_option_all_slaves_active_set(bond, new_value);
+ ret = bond_opt_tryset_rtnl(bond, BOND_OPT_ALL_SLAVES_ACTIVE,
+ (char *)buf);
if (!ret)
ret = count;
- rtnl_unlock();
return ret;
}
static DEVICE_ATTR(all_slaves_active, S_IRUGO | S_IWUSR,
struct device_attribute *attr,
const char *buf, size_t count)
{
- int new_value, ret = count;
struct bonding *bond = to_bond(d);
+ int ret;
- if (sscanf(buf, "%d", &new_value) != 1) {
- pr_err("%s: no resend_igmp value specified.\n",
- bond->dev->name);
- return -EINVAL;
- }
-
- if (!rtnl_trylock())
- return restart_syscall();
-
- ret = bond_option_resend_igmp_set(bond, new_value);
+ ret = bond_opt_tryset_rtnl(bond, BOND_OPT_RESEND_IGMP, (char *)buf);
if (!ret)
ret = count;
- rtnl_unlock();
return ret;
}
const char *buf, size_t count)
{
struct bonding *bond = to_bond(d);
- int new_value, ret;
-
- if (sscanf(buf, "%d", &new_value) != 1) {
- pr_err("%s: no lp interval value specified.\n",
- bond->dev->name);
- return -EINVAL;
- }
-
- if (!rtnl_trylock())
- return restart_syscall();
+ int ret;
- ret = bond_option_lp_interval_set(bond, new_value);
+ ret = bond_opt_tryset_rtnl(bond, BOND_OPT_LP_INTERVAL, (char *)buf);
if (!ret)
ret = count;
- rtnl_unlock();
return ret;
}