diff options
-rw-r--r-- | drivers/net/bonding/bond_main.c | 21 | ||||
-rw-r--r-- | drivers/net/bonding/bond_netlink.c | 4 | ||||
-rw-r--r-- | drivers/net/bonding/bond_options.c | 53 | ||||
-rw-r--r-- | drivers/net/bonding/bond_options.h | 3 | ||||
-rw-r--r-- | drivers/net/bonding/bond_sysfs.c | 27 | ||||
-rw-r--r-- | drivers/net/bonding/bonding.h | 2 |
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 | ||
217 | const 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 | |||
228 | const struct bond_parm_tbl xmit_hashtype_tbl[] = { | 217 | const 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) | |||
4028 | static int bond_check_params(struct bond_params *params) | 4017 | static 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 | ||
22 | static 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 | |||
22 | static struct bond_option bond_opts[] = { | 33 | static 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, | |||
160 | static void bond_opt_dep_print(struct bonding *bond, | 179 | static 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 | ||
171 | static void bond_opt_error_interpret(struct bonding *bond, | 193 | static 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 | ||
293 | int bond_option_mode_set(struct bonding *bond, int mode) | 315 | int 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 */ |
40 | enum { | 40 | enum { |
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 | |||
102 | int 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 | ||
272 | static ssize_t bonding_store_mode(struct device *d, | 273 | static 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 | } |
299 | static DEVICE_ATTR(mode, S_IRUGO | S_IWUSR, | 286 | static 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); | |||
452 | unsigned int bond_get_num_tx_queues(void); | 452 | unsigned int bond_get_num_tx_queues(void); |
453 | int bond_netlink_init(void); | 453 | int bond_netlink_init(void); |
454 | void bond_netlink_fini(void); | 454 | void bond_netlink_fini(void); |
455 | int bond_option_mode_set(struct bonding *bond, int mode); | ||
456 | int bond_option_active_slave_set(struct bonding *bond, struct net_device *slave_dev); | 455 | int bond_option_active_slave_set(struct bonding *bond, struct net_device *slave_dev); |
457 | int bond_option_miimon_set(struct bonding *bond, int miimon); | 456 | int bond_option_miimon_set(struct bonding *bond, int miimon); |
458 | int bond_option_updelay_set(struct bonding *bond, int updelay); | 457 | int 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 */ |
564 | extern int bond_net_id; | 563 | extern int bond_net_id; |
565 | extern const struct bond_parm_tbl bond_lacp_tbl[]; | 564 | extern const struct bond_parm_tbl bond_lacp_tbl[]; |
566 | extern const struct bond_parm_tbl bond_mode_tbl[]; | ||
567 | extern const struct bond_parm_tbl xmit_hashtype_tbl[]; | 565 | extern const struct bond_parm_tbl xmit_hashtype_tbl[]; |
568 | extern const struct bond_parm_tbl arp_validate_tbl[]; | 566 | extern const struct bond_parm_tbl arp_validate_tbl[]; |
569 | extern const struct bond_parm_tbl arp_all_targets_tbl[]; | 567 | extern const struct bond_parm_tbl arp_all_targets_tbl[]; |