aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNikolay Aleksandrov <nikolay@redhat.com>2014-01-22 08:53:17 -0500
committerDavid S. Miller <davem@davemloft.net>2014-01-22 18:38:41 -0500
commit2b3798d5e1377ce6c67993bb271754c9c5ab4833 (patch)
tree29e37d916f2312c62d9e2f46a6cbe54125e1f3bb
parent0911736245df19b423a3b156f6709e7bba48b18a (diff)
bonding: convert mode setting to use the new option API
This patch makes the bond's mode setting use the new option API and adds support for dependency printing which relies on having an entry for the mode option in the bond_opts[] array. Also add the ability to print the mode name when mode dependency fails and fix some trivial/style errors. Signed-off-by: Nikolay Aleksandrov <nikolay@redhat.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/bonding/bond_main.c21
-rw-r--r--drivers/net/bonding/bond_netlink.c4
-rw-r--r--drivers/net/bonding/bond_options.c53
-rw-r--r--drivers/net/bonding/bond_options.h3
-rw-r--r--drivers/net/bonding/bond_sysfs.c27
-rw-r--r--drivers/net/bonding/bonding.h2
6 files changed, 48 insertions, 62 deletions
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index f100bd958b88..7a04f0f8449e 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -214,17 +214,6 @@ const struct bond_parm_tbl bond_lacp_tbl[] = {
214{ NULL, -1}, 214{ NULL, -1},
215}; 215};
216 216
217const struct bond_parm_tbl bond_mode_tbl[] = {
218{ "balance-rr", BOND_MODE_ROUNDROBIN},
219{ "active-backup", BOND_MODE_ACTIVEBACKUP},
220{ "balance-xor", BOND_MODE_XOR},
221{ "broadcast", BOND_MODE_BROADCAST},
222{ "802.3ad", BOND_MODE_8023AD},
223{ "balance-tlb", BOND_MODE_TLB},
224{ "balance-alb", BOND_MODE_ALB},
225{ NULL, -1},
226};
227
228const struct bond_parm_tbl xmit_hashtype_tbl[] = { 217const struct bond_parm_tbl xmit_hashtype_tbl[] = {
229{ "layer2", BOND_XMIT_POLICY_LAYER2}, 218{ "layer2", BOND_XMIT_POLICY_LAYER2},
230{ "layer3+4", BOND_XMIT_POLICY_LAYER34}, 219{ "layer3+4", BOND_XMIT_POLICY_LAYER34},
@@ -4028,18 +4017,20 @@ int bond_parse_parm(const char *buf, const struct bond_parm_tbl *tbl)
4028static int bond_check_params(struct bond_params *params) 4017static int bond_check_params(struct bond_params *params)
4029{ 4018{
4030 int arp_validate_value, fail_over_mac_value, primary_reselect_value, i; 4019 int arp_validate_value, fail_over_mac_value, primary_reselect_value, i;
4020 struct bond_opt_value newval, *valptr;
4031 int arp_all_targets_value; 4021 int arp_all_targets_value;
4032 4022
4033 /* 4023 /*
4034 * Convert string parameters. 4024 * Convert string parameters.
4035 */ 4025 */
4036 if (mode) { 4026 if (mode) {
4037 bond_mode = bond_parse_parm(mode, bond_mode_tbl); 4027 bond_opt_initstr(&newval, mode);
4038 if (bond_mode == -1) { 4028 valptr = bond_opt_parse(bond_opt_get(BOND_OPT_MODE), &newval);
4039 pr_err("Error: Invalid bonding mode \"%s\"\n", 4029 if (!valptr) {
4040 mode == NULL ? "NULL" : mode); 4030 pr_err("Error: Invalid bonding mode \"%s\"\n", mode);
4041 return -EINVAL; 4031 return -EINVAL;
4042 } 4032 }
4033 bond_mode = valptr->value;
4043 } 4034 }
4044 4035
4045 if (xmit_hash_policy) { 4036 if (xmit_hash_policy) {
diff --git a/drivers/net/bonding/bond_netlink.c b/drivers/net/bonding/bond_netlink.c
index e8526552790c..db3f672a5e2a 100644
--- a/drivers/net/bonding/bond_netlink.c
+++ b/drivers/net/bonding/bond_netlink.c
@@ -98,6 +98,7 @@ static int bond_changelink(struct net_device *bond_dev,
98 struct nlattr *tb[], struct nlattr *data[]) 98 struct nlattr *tb[], struct nlattr *data[])
99{ 99{
100 struct bonding *bond = netdev_priv(bond_dev); 100 struct bonding *bond = netdev_priv(bond_dev);
101 struct bond_opt_value newval;
101 int miimon = 0; 102 int miimon = 0;
102 int err; 103 int err;
103 104
@@ -107,7 +108,8 @@ static int bond_changelink(struct net_device *bond_dev,
107 if (data[IFLA_BOND_MODE]) { 108 if (data[IFLA_BOND_MODE]) {
108 int mode = nla_get_u8(data[IFLA_BOND_MODE]); 109 int mode = nla_get_u8(data[IFLA_BOND_MODE]);
109 110
110 err = bond_option_mode_set(bond, mode); 111 bond_opt_initval(&newval, mode);
112 err = __bond_opt_set(bond, BOND_OPT_MODE, &newval);
111 if (err) 113 if (err)
112 return err; 114 return err;
113 } 115 }
diff --git a/drivers/net/bonding/bond_options.c b/drivers/net/bonding/bond_options.c
index 3ad140bfed1a..5696b2fb5cb4 100644
--- a/drivers/net/bonding/bond_options.c
+++ b/drivers/net/bonding/bond_options.c
@@ -19,7 +19,26 @@
19#include <linux/ctype.h> 19#include <linux/ctype.h>
20#include "bonding.h" 20#include "bonding.h"
21 21
22static struct bond_opt_value bond_mode_tbl[] = {
23 { "balance-rr", BOND_MODE_ROUNDROBIN, BOND_VALFLAG_DEFAULT},
24 { "active-backup", BOND_MODE_ACTIVEBACKUP, 0},
25 { "balance-xor", BOND_MODE_XOR, 0},
26 { "broadcast", BOND_MODE_BROADCAST, 0},
27 { "802.3ad", BOND_MODE_8023AD, 0},
28 { "balance-tlb", BOND_MODE_TLB, 0},
29 { "balance-alb", BOND_MODE_ALB, 0},
30 { NULL, -1, 0},
31};
32
22static struct bond_option bond_opts[] = { 33static struct bond_option bond_opts[] = {
34 [BOND_OPT_MODE] = {
35 .id = BOND_OPT_MODE,
36 .name = "mode",
37 .desc = "bond device mode",
38 .flags = BOND_OPTFLAG_NOSLAVES | BOND_OPTFLAG_IFDOWN,
39 .values = bond_mode_tbl,
40 .set = bond_option_mode_set
41 },
23 { } 42 { }
24}; 43};
25 44
@@ -160,12 +179,15 @@ static int bond_opt_check_deps(struct bonding *bond,
160static void bond_opt_dep_print(struct bonding *bond, 179static void bond_opt_dep_print(struct bonding *bond,
161 const struct bond_option *opt) 180 const struct bond_option *opt)
162{ 181{
182 struct bond_opt_value *modeval;
163 struct bond_params *params; 183 struct bond_params *params;
164 184
165 params = &bond->params; 185 params = &bond->params;
186 modeval = bond_opt_get_val(BOND_OPT_MODE, params->mode);
166 if (test_bit(params->mode, &opt->unsuppmodes)) 187 if (test_bit(params->mode, &opt->unsuppmodes))
167 pr_err("%s: option %s: mode dependency failed\n", 188 pr_err("%s: option %s: mode dependency failed, not supported in mode %s(%llu)\n",
168 bond->dev->name, opt->name); 189 bond->dev->name, opt->name,
190 modeval->string, modeval->value);
169} 191}
170 192
171static void bond_opt_error_interpret(struct bonding *bond, 193static void bond_opt_error_interpret(struct bonding *bond,
@@ -290,29 +312,11 @@ struct bond_option *bond_opt_get(unsigned int option)
290 return &bond_opts[option]; 312 return &bond_opts[option];
291} 313}
292 314
293int bond_option_mode_set(struct bonding *bond, int mode) 315int bond_option_mode_set(struct bonding *bond, struct bond_opt_value *newval)
294{ 316{
295 if (bond_parm_tbl_lookup(mode, bond_mode_tbl) < 0) { 317 if (BOND_NO_USES_ARP(newval->value) && bond->params.arp_interval) {
296 pr_err("%s: Ignoring invalid mode value %d.\n",
297 bond->dev->name, mode);
298 return -EINVAL;
299 }
300
301 if (bond->dev->flags & IFF_UP) {
302 pr_err("%s: unable to update mode because interface is up.\n",
303 bond->dev->name);
304 return -EPERM;
305 }
306
307 if (bond_has_slaves(bond)) {
308 pr_err("%s: unable to update mode because bond has slaves.\n",
309 bond->dev->name);
310 return -EPERM;
311 }
312
313 if (BOND_NO_USES_ARP(mode) && bond->params.arp_interval) {
314 pr_info("%s: %s mode is incompatible with arp monitoring, start mii monitoring\n", 318 pr_info("%s: %s mode is incompatible with arp monitoring, start mii monitoring\n",
315 bond->dev->name, bond_mode_tbl[mode].modename); 319 bond->dev->name, newval->string);
316 /* disable arp monitoring */ 320 /* disable arp monitoring */
317 bond->params.arp_interval = 0; 321 bond->params.arp_interval = 0;
318 /* set miimon to default value */ 322 /* set miimon to default value */
@@ -323,7 +327,8 @@ int bond_option_mode_set(struct bonding *bond, int mode)
323 327
324 /* don't cache arp_validate between modes */ 328 /* don't cache arp_validate between modes */
325 bond->params.arp_validate = BOND_ARP_VALIDATE_NONE; 329 bond->params.arp_validate = BOND_ARP_VALIDATE_NONE;
326 bond->params.mode = mode; 330 bond->params.mode = newval->value;
331
327 return 0; 332 return 0;
328} 333}
329 334
diff --git a/drivers/net/bonding/bond_options.h b/drivers/net/bonding/bond_options.h
index e20f2ebaf5c3..11e6c0697aed 100644
--- a/drivers/net/bonding/bond_options.h
+++ b/drivers/net/bonding/bond_options.h
@@ -38,6 +38,7 @@ enum {
38 38
39/* Option IDs, their bit positions correspond to their IDs */ 39/* Option IDs, their bit positions correspond to their IDs */
40enum { 40enum {
41 BOND_OPT_MODE,
41 BOND_OPT_LAST 42 BOND_OPT_LAST
42}; 43};
43 44
@@ -97,4 +98,6 @@ static inline void __bond_opt_init(struct bond_opt_value *optval,
97} 98}
98#define bond_opt_initval(optval, value) __bond_opt_init(optval, NULL, value) 99#define bond_opt_initval(optval, value) __bond_opt_init(optval, NULL, value)
99#define bond_opt_initstr(optval, str) __bond_opt_init(optval, str, ULLONG_MAX) 100#define bond_opt_initstr(optval, str) __bond_opt_init(optval, str, ULLONG_MAX)
101
102int bond_option_mode_set(struct bonding *bond, struct bond_opt_value *newval);
100#endif /* _BOND_OPTIONS_H */ 103#endif /* _BOND_OPTIONS_H */
diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c
index c083e9a66ece..3e537e7b66a5 100644
--- a/drivers/net/bonding/bond_sysfs.c
+++ b/drivers/net/bonding/bond_sysfs.c
@@ -263,37 +263,24 @@ static ssize_t bonding_show_mode(struct device *d,
263 struct device_attribute *attr, char *buf) 263 struct device_attribute *attr, char *buf)
264{ 264{
265 struct bonding *bond = to_bond(d); 265 struct bonding *bond = to_bond(d);
266 struct bond_opt_value *val;
266 267
267 return sprintf(buf, "%s %d\n", 268 val = bond_opt_get_val(BOND_OPT_MODE, bond->params.mode);
268 bond_mode_tbl[bond->params.mode].modename, 269
269 bond->params.mode); 270 return sprintf(buf, "%s %d\n", val->string, bond->params.mode);
270} 271}
271 272
272static ssize_t bonding_store_mode(struct device *d, 273static ssize_t bonding_store_mode(struct device *d,
273 struct device_attribute *attr, 274 struct device_attribute *attr,
274 const char *buf, size_t count) 275 const char *buf, size_t count)
275{ 276{
276 int new_value, ret;
277 struct bonding *bond = to_bond(d); 277 struct bonding *bond = to_bond(d);
278 int ret;
278 279
279 new_value = bond_parse_parm(buf, bond_mode_tbl); 280 ret = bond_opt_tryset_rtnl(bond, BOND_OPT_MODE, (char *)buf);
280 if (new_value < 0) { 281 if (!ret)
281 pr_err("%s: Ignoring invalid mode value %.*s.\n",
282 bond->dev->name, (int)strlen(buf) - 1, buf);
283 return -EINVAL;
284 }
285 if (!rtnl_trylock())
286 return restart_syscall();
287
288 ret = bond_option_mode_set(bond, new_value);
289 if (!ret) {
290 pr_info("%s: setting mode to %s (%d).\n",
291 bond->dev->name, bond_mode_tbl[new_value].modename,
292 new_value);
293 ret = count; 282 ret = count;
294 }
295 283
296 rtnl_unlock();
297 return ret; 284 return ret;
298} 285}
299static DEVICE_ATTR(mode, S_IRUGO | S_IWUSR, 286static DEVICE_ATTR(mode, S_IRUGO | S_IWUSR,
diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h
index 8c3c94aa04d7..f8e2cab90020 100644
--- a/drivers/net/bonding/bonding.h
+++ b/drivers/net/bonding/bonding.h
@@ -452,7 +452,6 @@ void bond_setup(struct net_device *bond_dev);
452unsigned int bond_get_num_tx_queues(void); 452unsigned int bond_get_num_tx_queues(void);
453int bond_netlink_init(void); 453int bond_netlink_init(void);
454void bond_netlink_fini(void); 454void bond_netlink_fini(void);
455int bond_option_mode_set(struct bonding *bond, int mode);
456int bond_option_active_slave_set(struct bonding *bond, struct net_device *slave_dev); 455int bond_option_active_slave_set(struct bonding *bond, struct net_device *slave_dev);
457int bond_option_miimon_set(struct bonding *bond, int miimon); 456int bond_option_miimon_set(struct bonding *bond, int miimon);
458int bond_option_updelay_set(struct bonding *bond, int updelay); 457int bond_option_updelay_set(struct bonding *bond, int updelay);
@@ -563,7 +562,6 @@ static inline int bond_get_targets_ip(__be32 *targets, __be32 ip)
563/* exported from bond_main.c */ 562/* exported from bond_main.c */
564extern int bond_net_id; 563extern int bond_net_id;
565extern const struct bond_parm_tbl bond_lacp_tbl[]; 564extern const struct bond_parm_tbl bond_lacp_tbl[];
566extern const struct bond_parm_tbl bond_mode_tbl[];
567extern const struct bond_parm_tbl xmit_hashtype_tbl[]; 565extern const struct bond_parm_tbl xmit_hashtype_tbl[];
568extern const struct bond_parm_tbl arp_validate_tbl[]; 566extern const struct bond_parm_tbl arp_validate_tbl[];
569extern const struct bond_parm_tbl arp_all_targets_tbl[]; 567extern const struct bond_parm_tbl arp_all_targets_tbl[];