diff options
author | sfeldma@cumulusnetworks.com <sfeldma@cumulusnetworks.com> | 2013-12-12 17:10:09 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2013-12-14 01:07:31 -0500 |
commit | c7461f9bf5a11bf88fdbd05b26c6d55b77dcd46d (patch) | |
tree | 2c80c47d2ef00b0c4cdf64835865612c73682cfb /drivers/net/bonding | |
parent | 25852e29dfc58d249ad0db235996b36c33db6d61 (diff) |
bonding: add downdelay netlink support
Add IFLA_BOND_DOWNDELAY to allow get/set of bonding parameter
downdelay 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/net/bonding')
-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 | 39 | ||||
-rw-r--r-- | drivers/net/bonding/bonding.h | 1 |
4 files changed, 51 insertions, 31 deletions
diff --git a/drivers/net/bonding/bond_netlink.c b/drivers/net/bonding/bond_netlink.c index 086cf4f5f0a6..a0a2e8c32fe5 100644 --- a/drivers/net/bonding/bond_netlink.c +++ b/drivers/net/bonding/bond_netlink.c | |||
@@ -26,6 +26,7 @@ static const struct nla_policy bond_policy[IFLA_BOND_MAX + 1] = { | |||
26 | [IFLA_BOND_ACTIVE_SLAVE] = { .type = NLA_U32 }, | 26 | [IFLA_BOND_ACTIVE_SLAVE] = { .type = NLA_U32 }, |
27 | [IFLA_BOND_MIIMON] = { .type = NLA_U32 }, | 27 | [IFLA_BOND_MIIMON] = { .type = NLA_U32 }, |
28 | [IFLA_BOND_UPDELAY] = { .type = NLA_U32 }, | 28 | [IFLA_BOND_UPDELAY] = { .type = NLA_U32 }, |
29 | [IFLA_BOND_DOWNDELAY] = { .type = NLA_U32 }, | ||
29 | }; | 30 | }; |
30 | 31 | ||
31 | static int bond_validate(struct nlattr *tb[], struct nlattr *data[]) | 32 | static int bond_validate(struct nlattr *tb[], struct nlattr *data[]) |
@@ -85,6 +86,13 @@ static int bond_changelink(struct net_device *bond_dev, | |||
85 | if (err) | 86 | if (err) |
86 | return err; | 87 | return err; |
87 | } | 88 | } |
89 | if (data[IFLA_BOND_DOWNDELAY]) { | ||
90 | int downdelay = nla_get_u32(data[IFLA_BOND_DOWNDELAY]); | ||
91 | |||
92 | err = bond_option_downdelay_set(bond, downdelay); | ||
93 | if (err) | ||
94 | return err; | ||
95 | } | ||
88 | return 0; | 96 | return 0; |
89 | } | 97 | } |
90 | 98 | ||
@@ -106,6 +114,7 @@ static size_t bond_get_size(const struct net_device *bond_dev) | |||
106 | nla_total_size(sizeof(u32)) + /* IFLA_BOND_ACTIVE_SLAVE */ | 114 | nla_total_size(sizeof(u32)) + /* IFLA_BOND_ACTIVE_SLAVE */ |
107 | nla_total_size(sizeof(u32)) + /* IFLA_BOND_MIIMON */ | 115 | nla_total_size(sizeof(u32)) + /* IFLA_BOND_MIIMON */ |
108 | nla_total_size(sizeof(u32)) + /* IFLA_BOND_UPDELAY */ | 116 | nla_total_size(sizeof(u32)) + /* IFLA_BOND_UPDELAY */ |
117 | nla_total_size(sizeof(u32)) + /* IFLA_BOND_DOWNDELAY */ | ||
109 | 0; | 118 | 0; |
110 | } | 119 | } |
111 | 120 | ||
@@ -129,6 +138,10 @@ static int bond_fill_info(struct sk_buff *skb, | |||
129 | bond->params.updelay * bond->params.miimon)) | 138 | bond->params.updelay * bond->params.miimon)) |
130 | goto nla_put_failure; | 139 | goto nla_put_failure; |
131 | 140 | ||
141 | if (nla_put_u32(skb, IFLA_BOND_DOWNDELAY, | ||
142 | bond->params.downdelay * bond->params.miimon)) | ||
143 | goto nla_put_failure; | ||
144 | |||
132 | return 0; | 145 | return 0; |
133 | 146 | ||
134 | nla_put_failure: | 147 | nla_put_failure: |
diff --git a/drivers/net/bonding/bond_options.c b/drivers/net/bonding/bond_options.c index ae94b847ffcc..2914d649ee34 100644 --- a/drivers/net/bonding/bond_options.c +++ b/drivers/net/bonding/bond_options.c | |||
@@ -216,3 +216,32 @@ int bond_option_updelay_set(struct bonding *bond, int updelay) | |||
216 | 216 | ||
217 | return 0; | 217 | return 0; |
218 | } | 218 | } |
219 | |||
220 | int bond_option_downdelay_set(struct bonding *bond, int downdelay) | ||
221 | { | ||
222 | if (!(bond->params.miimon)) { | ||
223 | pr_err("%s: Unable to set down delay as MII monitoring is disabled\n", | ||
224 | bond->dev->name); | ||
225 | return -EPERM; | ||
226 | } | ||
227 | |||
228 | if (downdelay < 0) { | ||
229 | pr_err("%s: Invalid down delay value %d not in range %d-%d; rejected.\n", | ||
230 | bond->dev->name, downdelay, 0, INT_MAX); | ||
231 | return -EINVAL; | ||
232 | } else { | ||
233 | if ((downdelay % bond->params.miimon) != 0) { | ||
234 | pr_warn("%s: Warning: down delay (%d) is not a multiple of miimon (%d), delay rounded to %d ms\n", | ||
235 | bond->dev->name, downdelay, | ||
236 | bond->params.miimon, | ||
237 | (downdelay / bond->params.miimon) * | ||
238 | bond->params.miimon); | ||
239 | } | ||
240 | bond->params.downdelay = downdelay / bond->params.miimon; | ||
241 | pr_info("%s: Setting down delay to %d.\n", | ||
242 | bond->dev->name, | ||
243 | bond->params.downdelay * bond->params.miimon); | ||
244 | } | ||
245 | |||
246 | return 0; | ||
247 | } | ||
diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c index 4dcbec4e07c0..bec20bc08d31 100644 --- a/drivers/net/bonding/bond_sysfs.c +++ b/drivers/net/bonding/bond_sysfs.c | |||
@@ -689,44 +689,21 @@ static ssize_t bonding_store_downdelay(struct device *d, | |||
689 | struct device_attribute *attr, | 689 | struct device_attribute *attr, |
690 | const char *buf, size_t count) | 690 | const char *buf, size_t count) |
691 | { | 691 | { |
692 | int new_value, ret = count; | 692 | int new_value, ret; |
693 | struct bonding *bond = to_bond(d); | 693 | struct bonding *bond = to_bond(d); |
694 | 694 | ||
695 | if (!rtnl_trylock()) | ||
696 | return restart_syscall(); | ||
697 | if (!(bond->params.miimon)) { | ||
698 | pr_err("%s: Unable to set down delay as MII monitoring is disabled\n", | ||
699 | bond->dev->name); | ||
700 | ret = -EPERM; | ||
701 | goto out; | ||
702 | } | ||
703 | |||
704 | if (sscanf(buf, "%d", &new_value) != 1) { | 695 | if (sscanf(buf, "%d", &new_value) != 1) { |
705 | pr_err("%s: no down delay value specified.\n", bond->dev->name); | 696 | pr_err("%s: no down delay value specified.\n", bond->dev->name); |
706 | ret = -EINVAL; | 697 | return -EINVAL; |
707 | goto out; | ||
708 | } | 698 | } |
709 | if (new_value < 0) { | ||
710 | pr_err("%s: Invalid down delay value %d not in range %d-%d; rejected.\n", | ||
711 | bond->dev->name, new_value, 0, INT_MAX); | ||
712 | ret = -EINVAL; | ||
713 | goto out; | ||
714 | } else { | ||
715 | if ((new_value % bond->params.miimon) != 0) { | ||
716 | pr_warning("%s: Warning: down delay (%d) is not a multiple of miimon (%d), delay rounded to %d ms\n", | ||
717 | bond->dev->name, new_value, | ||
718 | bond->params.miimon, | ||
719 | (new_value / bond->params.miimon) * | ||
720 | bond->params.miimon); | ||
721 | } | ||
722 | bond->params.downdelay = new_value / bond->params.miimon; | ||
723 | pr_info("%s: Setting down delay to %d.\n", | ||
724 | bond->dev->name, | ||
725 | bond->params.downdelay * bond->params.miimon); | ||
726 | 699 | ||
727 | } | 700 | if (!rtnl_trylock()) |
701 | return restart_syscall(); | ||
702 | |||
703 | ret = bond_option_downdelay_set(bond, new_value); | ||
704 | if (!ret) | ||
705 | ret = count; | ||
728 | 706 | ||
729 | out: | ||
730 | rtnl_unlock(); | 707 | rtnl_unlock(); |
731 | return ret; | 708 | return ret; |
732 | } | 709 | } |
diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h index 8a91f7187e51..f5749b18d168 100644 --- a/drivers/net/bonding/bonding.h +++ b/drivers/net/bonding/bonding.h | |||
@@ -441,6 +441,7 @@ int bond_option_mode_set(struct bonding *bond, int mode); | |||
441 | int bond_option_active_slave_set(struct bonding *bond, struct net_device *slave_dev); | 441 | int bond_option_active_slave_set(struct bonding *bond, struct net_device *slave_dev); |
442 | int bond_option_miimon_set(struct bonding *bond, int miimon); | 442 | int bond_option_miimon_set(struct bonding *bond, int miimon); |
443 | int bond_option_updelay_set(struct bonding *bond, int updelay); | 443 | int bond_option_updelay_set(struct bonding *bond, int updelay); |
444 | int bond_option_downdelay_set(struct bonding *bond, int downdelay); | ||
444 | struct net_device *bond_option_active_slave_get_rcu(struct bonding *bond); | 445 | struct net_device *bond_option_active_slave_get_rcu(struct bonding *bond); |
445 | struct net_device *bond_option_active_slave_get(struct bonding *bond); | 446 | struct net_device *bond_option_active_slave_get(struct bonding *bond); |
446 | 447 | ||