diff options
author | sfeldma@cumulusnetworks.com <sfeldma@cumulusnetworks.com> | 2013-12-13 02:10:02 +0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2013-12-14 10:07:31 +0400 |
commit | 25852e29dfc58d249ad0db235996b36c33db6d61 (patch) | |
tree | 9bd0ce9103aed2d5c40b2988260f03e65b1a1b3c /drivers | |
parent | eecdaa6e20284efbe9e76eebd44eac2b22f7b5d7 (diff) | |
download | linux-25852e29dfc58d249ad0db235996b36c33db6d61.tar.xz |
bonding: add updelay netlink support
Add IFLA_BOND_UPDELAY to allow get/set of bonding parameter
updelay via netlink.
Signed-off-by: Scott Feldman <sfeldma@cumulusnetworks.com>
Signed-off-by: Jiri Pirko <jiri@resnulli.us>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/net/bonding/bond_netlink.c | 13 | ||||
-rw-r--r-- | drivers/net/bonding/bond_options.c | 29 | ||||
-rw-r--r-- | drivers/net/bonding/bond_sysfs.c | 42 | ||||
-rw-r--r-- | drivers/net/bonding/bonding.h | 1 |
4 files changed, 53 insertions, 32 deletions
diff --git a/drivers/net/bonding/bond_netlink.c b/drivers/net/bonding/bond_netlink.c index 28a88beb749b..086cf4f5f0a6 100644 --- a/drivers/net/bonding/bond_netlink.c +++ b/drivers/net/bonding/bond_netlink.c @@ -25,6 +25,7 @@ static const struct nla_policy bond_policy[IFLA_BOND_MAX + 1] = { [IFLA_BOND_MODE] = { .type = NLA_U8 }, [IFLA_BOND_ACTIVE_SLAVE] = { .type = NLA_U32 }, [IFLA_BOND_MIIMON] = { .type = NLA_U32 }, + [IFLA_BOND_UPDELAY] = { .type = NLA_U32 }, }; static int bond_validate(struct nlattr *tb[], struct nlattr *data[]) @@ -77,6 +78,13 @@ static int bond_changelink(struct net_device *bond_dev, if (err) return err; } + if (data[IFLA_BOND_UPDELAY]) { + int updelay = nla_get_u32(data[IFLA_BOND_UPDELAY]); + + err = bond_option_updelay_set(bond, updelay); + if (err) + return err; + } return 0; } @@ -97,6 +105,7 @@ static size_t bond_get_size(const struct net_device *bond_dev) return nla_total_size(sizeof(u8)) + /* IFLA_BOND_MODE */ nla_total_size(sizeof(u32)) + /* IFLA_BOND_ACTIVE_SLAVE */ nla_total_size(sizeof(u32)) + /* IFLA_BOND_MIIMON */ + nla_total_size(sizeof(u32)) + /* IFLA_BOND_UPDELAY */ 0; } @@ -116,6 +125,10 @@ static int bond_fill_info(struct sk_buff *skb, if (nla_put_u32(skb, IFLA_BOND_MIIMON, bond->params.miimon)) goto nla_put_failure; + if (nla_put_u32(skb, IFLA_BOND_UPDELAY, + bond->params.updelay * bond->params.miimon)) + goto nla_put_failure; + return 0; nla_put_failure: diff --git a/drivers/net/bonding/bond_options.c b/drivers/net/bonding/bond_options.c index 8ae42d36f11f..ae94b847ffcc 100644 --- a/drivers/net/bonding/bond_options.c +++ b/drivers/net/bonding/bond_options.c @@ -187,3 +187,32 @@ int bond_option_miimon_set(struct bonding *bond, int miimon) } return 0; } + +int bond_option_updelay_set(struct bonding *bond, int updelay) +{ + if (!(bond->params.miimon)) { + pr_err("%s: Unable to set up delay as MII monitoring is disabled\n", + bond->dev->name); + return -EPERM; + } + + if (updelay < 0) { + pr_err("%s: Invalid up delay value %d not in range %d-%d; rejected.\n", + bond->dev->name, updelay, 0, INT_MAX); + return -EINVAL; + } else { + if ((updelay % bond->params.miimon) != 0) { + pr_warn("%s: Warning: up delay (%d) is not a multiple of miimon (%d), updelay rounded to %d ms\n", + bond->dev->name, updelay, + bond->params.miimon, + (updelay / bond->params.miimon) * + bond->params.miimon); + } + bond->params.updelay = updelay / bond->params.miimon; + pr_info("%s: Setting up delay to %d.\n", + bond->dev->name, + bond->params.updelay * bond->params.miimon); + } + + return 0; +} diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c index d6d6fc7812d5..4dcbec4e07c0 100644 --- a/drivers/net/bonding/bond_sysfs.c +++ b/drivers/net/bonding/bond_sysfs.c @@ -747,44 +747,22 @@ static ssize_t bonding_store_updelay(struct device *d, struct device_attribute *attr, const char *buf, size_t count) { - int new_value, ret = count; + int new_value, ret; struct bonding *bond = to_bond(d); - if (!rtnl_trylock()) - return restart_syscall(); - if (!(bond->params.miimon)) { - pr_err("%s: Unable to set up delay as MII monitoring is disabled\n", - bond->dev->name); - ret = -EPERM; - goto out; - } - if (sscanf(buf, "%d", &new_value) != 1) { pr_err("%s: no up delay value specified.\n", - bond->dev->name); - ret = -EINVAL; - goto out; - } - if (new_value < 0) { - pr_err("%s: Invalid up delay value %d not in range %d-%d; rejected.\n", - bond->dev->name, new_value, 0, INT_MAX); - ret = -EINVAL; - goto out; - } else { - if ((new_value % bond->params.miimon) != 0) { - pr_warning("%s: Warning: up delay (%d) is not a multiple of miimon (%d), updelay rounded to %d ms\n", - bond->dev->name, new_value, - bond->params.miimon, - (new_value / bond->params.miimon) * - bond->params.miimon); - } - bond->params.updelay = new_value / bond->params.miimon; - pr_info("%s: Setting up delay to %d.\n", - bond->dev->name, - bond->params.updelay * bond->params.miimon); + bond->dev->name); + return -EINVAL; } -out: + if (!rtnl_trylock()) + return restart_syscall(); + + ret = bond_option_updelay_set(bond, new_value); + if (!ret) + ret = count; + rtnl_unlock(); return ret; } diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h index b146479d5859..8a91f7187e51 100644 --- a/drivers/net/bonding/bonding.h +++ b/drivers/net/bonding/bonding.h @@ -440,6 +440,7 @@ void bond_netlink_fini(void); int bond_option_mode_set(struct bonding *bond, int mode); int bond_option_active_slave_set(struct bonding *bond, struct net_device *slave_dev); int bond_option_miimon_set(struct bonding *bond, int miimon); +int bond_option_updelay_set(struct bonding *bond, int updelay); struct net_device *bond_option_active_slave_get_rcu(struct bonding *bond); struct net_device *bond_option_active_slave_get(struct bonding *bond); |