diff options
author | Jiri Pirko <jiri@resnulli.us> | 2013-10-18 11:43:34 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2013-10-19 18:58:45 -0400 |
commit | 72be35fee6eda2fad7122f7f0c959effa3b2b791 (patch) | |
tree | 7b944a0339519191f7e53927e5628bea4445916a /drivers | |
parent | 0a2a78c4a95240e658272bd7cd7422a529e4eb4a (diff) |
bonding: move mode setting into separate function
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/Makefile | 2 | ||||
-rw-r--r-- | drivers/net/bonding/bond_options.c | 55 | ||||
-rw-r--r-- | drivers/net/bonding/bond_sysfs.c | 45 | ||||
-rw-r--r-- | drivers/net/bonding/bonding.h | 9 |
4 files changed, 74 insertions, 37 deletions
diff --git a/drivers/net/bonding/Makefile b/drivers/net/bonding/Makefile index 09e8b2c83afe..5a5d720da929 100644 --- a/drivers/net/bonding/Makefile +++ b/drivers/net/bonding/Makefile | |||
@@ -4,7 +4,7 @@ | |||
4 | 4 | ||
5 | obj-$(CONFIG_BONDING) += bonding.o | 5 | obj-$(CONFIG_BONDING) += bonding.o |
6 | 6 | ||
7 | bonding-objs := bond_main.o bond_3ad.o bond_alb.o bond_sysfs.o bond_debugfs.o bond_netlink.o | 7 | bonding-objs := bond_main.o bond_3ad.o bond_alb.o bond_sysfs.o bond_debugfs.o bond_netlink.o bond_options.o |
8 | 8 | ||
9 | proc-$(CONFIG_PROC_FS) += bond_procfs.o | 9 | proc-$(CONFIG_PROC_FS) += bond_procfs.o |
10 | bonding-objs += $(proc-y) | 10 | bonding-objs += $(proc-y) |
diff --git a/drivers/net/bonding/bond_options.c b/drivers/net/bonding/bond_options.c new file mode 100644 index 000000000000..294b7660b054 --- /dev/null +++ b/drivers/net/bonding/bond_options.c | |||
@@ -0,0 +1,55 @@ | |||
1 | /* | ||
2 | * drivers/net/bond/bond_options.c - bonding options | ||
3 | * Copyright (c) 2013 Jiri Pirko <jiri@resnulli.us> | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License as published by | ||
7 | * the Free Software Foundation; either version 2 of the License, or | ||
8 | * (at your option) any later version. | ||
9 | */ | ||
10 | |||
11 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
12 | |||
13 | #include <linux/errno.h> | ||
14 | #include <linux/if.h> | ||
15 | #include "bonding.h" | ||
16 | |||
17 | static bool bond_mode_is_valid(int mode) | ||
18 | { | ||
19 | int i; | ||
20 | |||
21 | for (i = 0; bond_mode_tbl[i].modename; i++); | ||
22 | |||
23 | return mode >= 0 && mode < i; | ||
24 | } | ||
25 | |||
26 | int bond_option_mode_set(struct bonding *bond, int mode) | ||
27 | { | ||
28 | if (!bond_mode_is_valid(mode)) { | ||
29 | pr_err("invalid mode value %d.\n", mode); | ||
30 | return -EINVAL; | ||
31 | } | ||
32 | |||
33 | if (bond->dev->flags & IFF_UP) { | ||
34 | pr_err("%s: unable to update mode because interface is up.\n", | ||
35 | bond->dev->name); | ||
36 | return -EPERM; | ||
37 | } | ||
38 | |||
39 | if (bond_has_slaves(bond)) { | ||
40 | pr_err("%s: unable to update mode because bond has slaves.\n", | ||
41 | bond->dev->name); | ||
42 | return -EPERM; | ||
43 | } | ||
44 | |||
45 | if (BOND_MODE_IS_LB(mode) && bond->params.arp_interval) { | ||
46 | pr_err("%s: %s mode is incompatible with arp monitoring.\n", | ||
47 | bond->dev->name, bond_mode_tbl[mode].modename); | ||
48 | return -EINVAL; | ||
49 | } | ||
50 | |||
51 | /* don't cache arp_validate between modes */ | ||
52 | bond->params.arp_validate = BOND_ARP_VALIDATE_NONE; | ||
53 | bond->params.mode = mode; | ||
54 | return 0; | ||
55 | } | ||
diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c index 03bed0ca935e..c234cec10e05 100644 --- a/drivers/net/bonding/bond_sysfs.c +++ b/drivers/net/bonding/bond_sysfs.c | |||
@@ -283,49 +283,26 @@ static ssize_t bonding_store_mode(struct device *d, | |||
283 | struct device_attribute *attr, | 283 | struct device_attribute *attr, |
284 | const char *buf, size_t count) | 284 | const char *buf, size_t count) |
285 | { | 285 | { |
286 | int new_value, ret = count; | 286 | int new_value, ret; |
287 | struct bonding *bond = to_bond(d); | 287 | struct bonding *bond = to_bond(d); |
288 | 288 | ||
289 | if (!rtnl_trylock()) | ||
290 | return restart_syscall(); | ||
291 | |||
292 | if (bond->dev->flags & IFF_UP) { | ||
293 | pr_err("unable to update mode of %s because interface is up.\n", | ||
294 | bond->dev->name); | ||
295 | ret = -EPERM; | ||
296 | goto out; | ||
297 | } | ||
298 | |||
299 | if (bond_has_slaves(bond)) { | ||
300 | pr_err("unable to update mode of %s because it has slaves.\n", | ||
301 | bond->dev->name); | ||
302 | ret = -EPERM; | ||
303 | goto out; | ||
304 | } | ||
305 | |||
306 | new_value = bond_parse_parm(buf, bond_mode_tbl); | 289 | new_value = bond_parse_parm(buf, bond_mode_tbl); |
307 | if (new_value < 0) { | 290 | if (new_value < 0) { |
308 | pr_err("%s: Ignoring invalid mode value %.*s.\n", | 291 | pr_err("%s: Ignoring invalid mode value %.*s.\n", |
309 | bond->dev->name, (int)strlen(buf) - 1, buf); | 292 | bond->dev->name, (int)strlen(buf) - 1, buf); |
310 | ret = -EINVAL; | 293 | return -EINVAL; |
311 | goto out; | ||
312 | } | 294 | } |
313 | if ((new_value == BOND_MODE_ALB || | 295 | if (!rtnl_trylock()) |
314 | new_value == BOND_MODE_TLB) && | 296 | return restart_syscall(); |
315 | bond->params.arp_interval) { | 297 | |
316 | pr_err("%s: %s mode is incompatible with arp monitoring.\n", | 298 | ret = bond_option_mode_set(bond, new_value); |
317 | bond->dev->name, bond_mode_tbl[new_value].modename); | 299 | if (!ret) { |
318 | ret = -EINVAL; | 300 | pr_info("%s: setting mode to %s (%d).\n", |
319 | goto out; | 301 | bond->dev->name, bond_mode_tbl[new_value].modename, |
302 | new_value); | ||
303 | ret = count; | ||
320 | } | 304 | } |
321 | 305 | ||
322 | /* don't cache arp_validate between modes */ | ||
323 | bond->params.arp_validate = BOND_ARP_VALIDATE_NONE; | ||
324 | bond->params.mode = new_value; | ||
325 | pr_info("%s: setting mode to %s (%d).\n", | ||
326 | bond->dev->name, bond_mode_tbl[new_value].modename, | ||
327 | new_value); | ||
328 | out: | ||
329 | rtnl_unlock(); | 306 | rtnl_unlock(); |
330 | return ret; | 307 | return ret; |
331 | } | 308 | } |
diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h index a2a353bf9ea6..7446849a20c4 100644 --- a/drivers/net/bonding/bonding.h +++ b/drivers/net/bonding/bonding.h | |||
@@ -58,6 +58,11 @@ | |||
58 | #define TX_QUEUE_OVERRIDE(mode) \ | 58 | #define TX_QUEUE_OVERRIDE(mode) \ |
59 | (((mode) == BOND_MODE_ACTIVEBACKUP) || \ | 59 | (((mode) == BOND_MODE_ACTIVEBACKUP) || \ |
60 | ((mode) == BOND_MODE_ROUNDROBIN)) | 60 | ((mode) == BOND_MODE_ROUNDROBIN)) |
61 | |||
62 | #define BOND_MODE_IS_LB(mode) \ | ||
63 | (((mode) == BOND_MODE_TLB) || \ | ||
64 | ((mode) == BOND_MODE_ALB)) | ||
65 | |||
61 | /* | 66 | /* |
62 | * Less bad way to call ioctl from within the kernel; this needs to be | 67 | * Less bad way to call ioctl from within the kernel; this needs to be |
63 | * done some other way to get the call out of interrupt context. | 68 | * done some other way to get the call out of interrupt context. |
@@ -259,8 +264,7 @@ static inline struct bonding *bond_get_bond_by_slave(struct slave *slave) | |||
259 | 264 | ||
260 | static inline bool bond_is_lb(const struct bonding *bond) | 265 | static inline bool bond_is_lb(const struct bonding *bond) |
261 | { | 266 | { |
262 | return (bond->params.mode == BOND_MODE_TLB || | 267 | return BOND_MODE_IS_LB(bond->params.mode); |
263 | bond->params.mode == BOND_MODE_ALB); | ||
264 | } | 268 | } |
265 | 269 | ||
266 | static inline void bond_set_active_slave(struct slave *slave) | 270 | static inline void bond_set_active_slave(struct slave *slave) |
@@ -422,6 +426,7 @@ void bond_setup(struct net_device *bond_dev); | |||
422 | unsigned int bond_get_num_tx_queues(void); | 426 | unsigned int bond_get_num_tx_queues(void); |
423 | int bond_netlink_init(void); | 427 | int bond_netlink_init(void); |
424 | void bond_netlink_fini(void); | 428 | void bond_netlink_fini(void); |
429 | int bond_option_mode_set(struct bonding *bond, int mode); | ||
425 | 430 | ||
426 | struct bond_net { | 431 | struct bond_net { |
427 | struct net * net; /* Associated network namespace */ | 432 | struct net * net; /* Associated network namespace */ |