aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorJiri Pirko <jiri@resnulli.us>2013-10-18 11:43:34 -0400
committerDavid S. Miller <davem@davemloft.net>2013-10-19 18:58:45 -0400
commit72be35fee6eda2fad7122f7f0c959effa3b2b791 (patch)
tree7b944a0339519191f7e53927e5628bea4445916a /drivers
parent0a2a78c4a95240e658272bd7cd7422a529e4eb4a (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/Makefile2
-rw-r--r--drivers/net/bonding/bond_options.c55
-rw-r--r--drivers/net/bonding/bond_sysfs.c45
-rw-r--r--drivers/net/bonding/bonding.h9
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
5obj-$(CONFIG_BONDING) += bonding.o 5obj-$(CONFIG_BONDING) += bonding.o
6 6
7bonding-objs := bond_main.o bond_3ad.o bond_alb.o bond_sysfs.o bond_debugfs.o bond_netlink.o 7bonding-objs := bond_main.o bond_3ad.o bond_alb.o bond_sysfs.o bond_debugfs.o bond_netlink.o bond_options.o
8 8
9proc-$(CONFIG_PROC_FS) += bond_procfs.o 9proc-$(CONFIG_PROC_FS) += bond_procfs.o
10bonding-objs += $(proc-y) 10bonding-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
17static 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
26int 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);
328out:
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
260static inline bool bond_is_lb(const struct bonding *bond) 265static 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
266static inline void bond_set_active_slave(struct slave *slave) 270static inline void bond_set_active_slave(struct slave *slave)
@@ -422,6 +426,7 @@ void bond_setup(struct net_device *bond_dev);
422unsigned int bond_get_num_tx_queues(void); 426unsigned int bond_get_num_tx_queues(void);
423int bond_netlink_init(void); 427int bond_netlink_init(void);
424void bond_netlink_fini(void); 428void bond_netlink_fini(void);
429int bond_option_mode_set(struct bonding *bond, int mode);
425 430
426struct bond_net { 431struct bond_net {
427 struct net * net; /* Associated network namespace */ 432 struct net * net; /* Associated network namespace */