aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2013-10-19 18:59:25 -0400
committerDavid S. Miller <davem@davemloft.net>2013-10-19 18:59:25 -0400
commit97e592bd29cdadfb544f7850ad873b87d277b1ab (patch)
tree07d936d41e71ae5413b66f9b556194c0113f7a71
parentb1eda2ac3fa6bf23b27c7c70eda6885124c79ed3 (diff)
parentec76aa49855f6d6fea5e01de179fb57dd47c619d (diff)
Merge branch 'bonding'
Jiri Pirko says: ==================== bonding: introduce bonding options Netlink support This patchset basically allows "mode" and "active_slave" bonding options to be propagated and set up via standart RT Netlink interface. In future other options can be easily added as well. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/bonding/Makefile2
-rw-r--r--drivers/net/bonding/bond_main.c91
-rw-r--r--drivers/net/bonding/bond_netlink.c131
-rw-r--r--drivers/net/bonding/bond_options.c142
-rw-r--r--drivers/net/bonding/bond_sysfs.c127
-rw-r--r--drivers/net/bonding/bonding.h19
-rw-r--r--include/uapi/linux/if_link.h11
7 files changed, 337 insertions, 186 deletions
diff --git a/drivers/net/bonding/Makefile b/drivers/net/bonding/Makefile
index 4c21bf6b8b2f..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 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_main.c b/drivers/net/bonding/bond_main.c
index dfb4f6dd5de0..d90734fca918 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -1910,61 +1910,6 @@ static int bond_release_and_destroy(struct net_device *bond_dev,
1910 return ret; 1910 return ret;
1911} 1911}
1912 1912
1913/*
1914 * This function changes the active slave to slave <slave_dev>.
1915 * It returns -EINVAL in the following cases.
1916 * - <slave_dev> is not found in the list.
1917 * - There is not active slave now.
1918 * - <slave_dev> is already active.
1919 * - The link state of <slave_dev> is not BOND_LINK_UP.
1920 * - <slave_dev> is not running.
1921 * In these cases, this function does nothing.
1922 * In the other cases, current_slave pointer is changed and 0 is returned.
1923 */
1924static int bond_ioctl_change_active(struct net_device *bond_dev, struct net_device *slave_dev)
1925{
1926 struct bonding *bond = netdev_priv(bond_dev);
1927 struct slave *old_active = NULL;
1928 struct slave *new_active = NULL;
1929 int res = 0;
1930
1931 if (!USES_PRIMARY(bond->params.mode))
1932 return -EINVAL;
1933
1934 /* Verify that bond_dev is indeed the master of slave_dev */
1935 if (!(slave_dev->flags & IFF_SLAVE) ||
1936 !netdev_has_upper_dev(slave_dev, bond_dev))
1937 return -EINVAL;
1938
1939 read_lock(&bond->lock);
1940
1941 old_active = bond->curr_active_slave;
1942 new_active = bond_get_slave_by_dev(bond, slave_dev);
1943 /*
1944 * Changing to the current active: do nothing; return success.
1945 */
1946 if (new_active && new_active == old_active) {
1947 read_unlock(&bond->lock);
1948 return 0;
1949 }
1950
1951 if (new_active &&
1952 old_active &&
1953 new_active->link == BOND_LINK_UP &&
1954 IS_UP(new_active->dev)) {
1955 block_netpoll_tx();
1956 write_lock_bh(&bond->curr_slave_lock);
1957 bond_change_active_slave(bond, new_active);
1958 write_unlock_bh(&bond->curr_slave_lock);
1959 unblock_netpoll_tx();
1960 } else
1961 res = -EINVAL;
1962
1963 read_unlock(&bond->lock);
1964
1965 return res;
1966}
1967
1968static int bond_info_query(struct net_device *bond_dev, struct ifbond *info) 1913static int bond_info_query(struct net_device *bond_dev, struct ifbond *info)
1969{ 1914{
1970 struct bonding *bond = netdev_priv(bond_dev); 1915 struct bonding *bond = netdev_priv(bond_dev);
@@ -3257,6 +3202,7 @@ static struct rtnl_link_stats64 *bond_get_stats(struct net_device *bond_dev,
3257 3202
3258static int bond_do_ioctl(struct net_device *bond_dev, struct ifreq *ifr, int cmd) 3203static int bond_do_ioctl(struct net_device *bond_dev, struct ifreq *ifr, int cmd)
3259{ 3204{
3205 struct bonding *bond = netdev_priv(bond_dev);
3260 struct net_device *slave_dev = NULL; 3206 struct net_device *slave_dev = NULL;
3261 struct ifbond k_binfo; 3207 struct ifbond k_binfo;
3262 struct ifbond __user *u_binfo = NULL; 3208 struct ifbond __user *u_binfo = NULL;
@@ -3287,7 +3233,6 @@ static int bond_do_ioctl(struct net_device *bond_dev, struct ifreq *ifr, int cmd
3287 3233
3288 3234
3289 if (mii->reg_num == 1) { 3235 if (mii->reg_num == 1) {
3290 struct bonding *bond = netdev_priv(bond_dev);
3291 mii->val_out = 0; 3236 mii->val_out = 0;
3292 read_lock(&bond->lock); 3237 read_lock(&bond->lock);
3293 read_lock(&bond->curr_slave_lock); 3238 read_lock(&bond->curr_slave_lock);
@@ -3359,7 +3304,7 @@ static int bond_do_ioctl(struct net_device *bond_dev, struct ifreq *ifr, int cmd
3359 break; 3304 break;
3360 case BOND_CHANGE_ACTIVE_OLD: 3305 case BOND_CHANGE_ACTIVE_OLD:
3361 case SIOCBONDCHANGEACTIVE: 3306 case SIOCBONDCHANGEACTIVE:
3362 res = bond_ioctl_change_active(bond_dev, slave_dev); 3307 res = bond_option_active_slave_set(bond, slave_dev);
3363 break; 3308 break;
3364 default: 3309 default:
3365 res = -EOPNOTSUPP; 3310 res = -EOPNOTSUPP;
@@ -3951,7 +3896,7 @@ static void bond_destructor(struct net_device *bond_dev)
3951 free_netdev(bond_dev); 3896 free_netdev(bond_dev);
3952} 3897}
3953 3898
3954static void bond_setup(struct net_device *bond_dev) 3899void bond_setup(struct net_device *bond_dev)
3955{ 3900{
3956 struct bonding *bond = netdev_priv(bond_dev); 3901 struct bonding *bond = netdev_priv(bond_dev);
3957 3902
@@ -4451,32 +4396,11 @@ static int bond_init(struct net_device *bond_dev)
4451 return 0; 4396 return 0;
4452} 4397}
4453 4398
4454static int bond_validate(struct nlattr *tb[], struct nlattr *data[]) 4399unsigned int bond_get_num_tx_queues(void)
4455{
4456 if (tb[IFLA_ADDRESS]) {
4457 if (nla_len(tb[IFLA_ADDRESS]) != ETH_ALEN)
4458 return -EINVAL;
4459 if (!is_valid_ether_addr(nla_data(tb[IFLA_ADDRESS])))
4460 return -EADDRNOTAVAIL;
4461 }
4462 return 0;
4463}
4464
4465static unsigned int bond_get_num_tx_queues(void)
4466{ 4400{
4467 return tx_queues; 4401 return tx_queues;
4468} 4402}
4469 4403
4470static struct rtnl_link_ops bond_link_ops __read_mostly = {
4471 .kind = "bond",
4472 .priv_size = sizeof(struct bonding),
4473 .setup = bond_setup,
4474 .validate = bond_validate,
4475 .get_num_tx_queues = bond_get_num_tx_queues,
4476 .get_num_rx_queues = bond_get_num_tx_queues, /* Use the same number
4477 as for TX queues */
4478};
4479
4480/* Create a new bond based on the specified name and bonding parameters. 4404/* Create a new bond based on the specified name and bonding parameters.
4481 * If name is NULL, obtain a suitable "bond%d" name for us. 4405 * If name is NULL, obtain a suitable "bond%d" name for us.
4482 * Caller must NOT hold rtnl_lock; we need to release it here before we 4406 * Caller must NOT hold rtnl_lock; we need to release it here before we
@@ -4563,7 +4487,7 @@ static int __init bonding_init(void)
4563 if (res) 4487 if (res)
4564 goto out; 4488 goto out;
4565 4489
4566 res = rtnl_link_register(&bond_link_ops); 4490 res = bond_netlink_init();
4567 if (res) 4491 if (res)
4568 goto err_link; 4492 goto err_link;
4569 4493
@@ -4579,7 +4503,7 @@ static int __init bonding_init(void)
4579out: 4503out:
4580 return res; 4504 return res;
4581err: 4505err:
4582 rtnl_link_unregister(&bond_link_ops); 4506 bond_netlink_fini();
4583err_link: 4507err_link:
4584 unregister_pernet_subsys(&bond_net_ops); 4508 unregister_pernet_subsys(&bond_net_ops);
4585 goto out; 4509 goto out;
@@ -4592,7 +4516,7 @@ static void __exit bonding_exit(void)
4592 4516
4593 bond_destroy_debugfs(); 4517 bond_destroy_debugfs();
4594 4518
4595 rtnl_link_unregister(&bond_link_ops); 4519 bond_netlink_fini();
4596 unregister_pernet_subsys(&bond_net_ops); 4520 unregister_pernet_subsys(&bond_net_ops);
4597 4521
4598#ifdef CONFIG_NET_POLL_CONTROLLER 4522#ifdef CONFIG_NET_POLL_CONTROLLER
@@ -4609,4 +4533,3 @@ MODULE_LICENSE("GPL");
4609MODULE_VERSION(DRV_VERSION); 4533MODULE_VERSION(DRV_VERSION);
4610MODULE_DESCRIPTION(DRV_DESCRIPTION ", v" DRV_VERSION); 4534MODULE_DESCRIPTION(DRV_DESCRIPTION ", v" DRV_VERSION);
4611MODULE_AUTHOR("Thomas Davis, tadavis@lbl.gov and many others"); 4535MODULE_AUTHOR("Thomas Davis, tadavis@lbl.gov and many others");
4612MODULE_ALIAS_RTNL_LINK("bond");
diff --git a/drivers/net/bonding/bond_netlink.c b/drivers/net/bonding/bond_netlink.c
new file mode 100644
index 000000000000..fe3500bb34e4
--- /dev/null
+++ b/drivers/net/bonding/bond_netlink.c
@@ -0,0 +1,131 @@
1/*
2 * drivers/net/bond/bond_netlink.c - Netlink interface for bonding
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/module.h>
14#include <linux/errno.h>
15#include <linux/netdevice.h>
16#include <linux/etherdevice.h>
17#include <linux/if_link.h>
18#include <linux/if_ether.h>
19#include <net/netlink.h>
20#include <net/rtnetlink.h>
21#include "bonding.h"
22
23static const struct nla_policy bond_policy[IFLA_BOND_MAX + 1] = {
24 [IFLA_BOND_MODE] = { .type = NLA_U8 },
25 [IFLA_BOND_ACTIVE_SLAVE] = { .type = NLA_U32 },
26};
27
28static int bond_validate(struct nlattr *tb[], struct nlattr *data[])
29{
30 if (tb[IFLA_ADDRESS]) {
31 if (nla_len(tb[IFLA_ADDRESS]) != ETH_ALEN)
32 return -EINVAL;
33 if (!is_valid_ether_addr(nla_data(tb[IFLA_ADDRESS])))
34 return -EADDRNOTAVAIL;
35 }
36 return 0;
37}
38
39static int bond_changelink(struct net_device *bond_dev,
40 struct nlattr *tb[], struct nlattr *data[])
41{
42 struct bonding *bond = netdev_priv(bond_dev);
43 int err;
44
45 if (data && data[IFLA_BOND_MODE]) {
46 int mode = nla_get_u8(data[IFLA_BOND_MODE]);
47
48 err = bond_option_mode_set(bond, mode);
49 if (err)
50 return err;
51 }
52 if (data && data[IFLA_BOND_ACTIVE_SLAVE]) {
53 int ifindex = nla_get_u32(data[IFLA_BOND_ACTIVE_SLAVE]);
54 struct net_device *slave_dev;
55
56 if (ifindex == 0) {
57 slave_dev = NULL;
58 } else {
59 slave_dev = __dev_get_by_index(dev_net(bond_dev),
60 ifindex);
61 if (!slave_dev)
62 return -ENODEV;
63 }
64 err = bond_option_active_slave_set(bond, slave_dev);
65 if (err)
66 return err;
67 }
68 return 0;
69}
70
71static int bond_newlink(struct net *src_net, struct net_device *bond_dev,
72 struct nlattr *tb[], struct nlattr *data[])
73{
74 int err;
75
76 err = bond_changelink(bond_dev, tb, data);
77 if (err < 0)
78 return err;
79
80 return register_netdevice(bond_dev);
81}
82
83static size_t bond_get_size(const struct net_device *bond_dev)
84{
85 return nla_total_size(sizeof(u8)); /* IFLA_BOND_MODE */
86 + nla_total_size(sizeof(u32)); /* IFLA_BOND_ACTIVE_SLAVE */
87}
88
89static int bond_fill_info(struct sk_buff *skb,
90 const struct net_device *bond_dev)
91{
92 struct bonding *bond = netdev_priv(bond_dev);
93 struct net_device *slave_dev = bond_option_active_slave_get(bond);
94
95 if (nla_put_u8(skb, IFLA_BOND_MODE, bond->params.mode) ||
96 (slave_dev &&
97 nla_put_u32(skb, IFLA_BOND_ACTIVE_SLAVE, slave_dev->ifindex)))
98 goto nla_put_failure;
99 return 0;
100
101nla_put_failure:
102 return -EMSGSIZE;
103}
104
105struct rtnl_link_ops bond_link_ops __read_mostly = {
106 .kind = "bond",
107 .priv_size = sizeof(struct bonding),
108 .setup = bond_setup,
109 .maxtype = IFLA_BOND_MAX,
110 .policy = bond_policy,
111 .validate = bond_validate,
112 .newlink = bond_newlink,
113 .changelink = bond_changelink,
114 .get_size = bond_get_size,
115 .fill_info = bond_fill_info,
116 .get_num_tx_queues = bond_get_num_tx_queues,
117 .get_num_rx_queues = bond_get_num_tx_queues, /* Use the same number
118 as for TX queues */
119};
120
121int __init bond_netlink_init(void)
122{
123 return rtnl_link_register(&bond_link_ops);
124}
125
126void __exit bond_netlink_fini(void)
127{
128 rtnl_link_unregister(&bond_link_ops);
129}
130
131MODULE_ALIAS_RTNL_LINK("bond");
diff --git a/drivers/net/bonding/bond_options.c b/drivers/net/bonding/bond_options.c
new file mode 100644
index 000000000000..9a5223c7b4d1
--- /dev/null
+++ b/drivers/net/bonding/bond_options.c
@@ -0,0 +1,142 @@
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 <linux/netdevice.h>
16#include <linux/rwlock.h>
17#include <linux/rcupdate.h>
18#include "bonding.h"
19
20static bool bond_mode_is_valid(int mode)
21{
22 int i;
23
24 for (i = 0; bond_mode_tbl[i].modename; i++);
25
26 return mode >= 0 && mode < i;
27}
28
29int bond_option_mode_set(struct bonding *bond, int mode)
30{
31 if (!bond_mode_is_valid(mode)) {
32 pr_err("invalid mode value %d.\n", mode);
33 return -EINVAL;
34 }
35
36 if (bond->dev->flags & IFF_UP) {
37 pr_err("%s: unable to update mode because interface is up.\n",
38 bond->dev->name);
39 return -EPERM;
40 }
41
42 if (bond_has_slaves(bond)) {
43 pr_err("%s: unable to update mode because bond has slaves.\n",
44 bond->dev->name);
45 return -EPERM;
46 }
47
48 if (BOND_MODE_IS_LB(mode) && bond->params.arp_interval) {
49 pr_err("%s: %s mode is incompatible with arp monitoring.\n",
50 bond->dev->name, bond_mode_tbl[mode].modename);
51 return -EINVAL;
52 }
53
54 /* don't cache arp_validate between modes */
55 bond->params.arp_validate = BOND_ARP_VALIDATE_NONE;
56 bond->params.mode = mode;
57 return 0;
58}
59
60static struct net_device *__bond_option_active_slave_get(struct bonding *bond,
61 struct slave *slave)
62{
63 return USES_PRIMARY(bond->params.mode) && slave ? slave->dev : NULL;
64}
65
66struct net_device *bond_option_active_slave_get_rcu(struct bonding *bond)
67{
68 struct slave *slave = rcu_dereference(bond->curr_active_slave);
69
70 return __bond_option_active_slave_get(bond, slave);
71}
72
73struct net_device *bond_option_active_slave_get(struct bonding *bond)
74{
75 return __bond_option_active_slave_get(bond, bond->curr_active_slave);
76}
77
78int bond_option_active_slave_set(struct bonding *bond,
79 struct net_device *slave_dev)
80{
81 int ret = 0;
82
83 if (slave_dev) {
84 if (!netif_is_bond_slave(slave_dev)) {
85 pr_err("Device %s is not bonding slave.\n",
86 slave_dev->name);
87 return -EINVAL;
88 }
89
90 if (bond->dev != netdev_master_upper_dev_get(slave_dev)) {
91 pr_err("%s: Device %s is not our slave.\n",
92 bond->dev->name, slave_dev->name);
93 return -EINVAL;
94 }
95 }
96
97 if (!USES_PRIMARY(bond->params.mode)) {
98 pr_err("%s: Unable to change active slave; %s is in mode %d\n",
99 bond->dev->name, bond->dev->name, bond->params.mode);
100 return -EINVAL;
101 }
102
103 block_netpoll_tx();
104 read_lock(&bond->lock);
105 write_lock_bh(&bond->curr_slave_lock);
106
107 /* check to see if we are clearing active */
108 if (!slave_dev) {
109 pr_info("%s: Clearing current active slave.\n",
110 bond->dev->name);
111 rcu_assign_pointer(bond->curr_active_slave, NULL);
112 bond_select_active_slave(bond);
113 } else {
114 struct slave *old_active = bond->curr_active_slave;
115 struct slave *new_active = bond_slave_get_rtnl(slave_dev);
116
117 BUG_ON(!new_active);
118
119 if (new_active == old_active) {
120 /* do nothing */
121 pr_info("%s: %s is already the current active slave.\n",
122 bond->dev->name, new_active->dev->name);
123 } else {
124 if (old_active && (new_active->link == BOND_LINK_UP) &&
125 IS_UP(new_active->dev)) {
126 pr_info("%s: Setting %s as active slave.\n",
127 bond->dev->name, new_active->dev->name);
128 bond_change_active_slave(bond, new_active);
129 } else {
130 pr_err("%s: Could not set %s as active slave; either %s is down or the link is down.\n",
131 bond->dev->name, new_active->dev->name,
132 new_active->dev->name);
133 ret = -EINVAL;
134 }
135 }
136 }
137
138 write_unlock_bh(&bond->curr_slave_lock);
139 read_unlock(&bond->lock);
140 unblock_netpoll_tx();
141 return ret;
142}
diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c
index 03bed0ca935e..47749c970a01 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}
@@ -1242,13 +1219,13 @@ static ssize_t bonding_show_active_slave(struct device *d,
1242 char *buf) 1219 char *buf)
1243{ 1220{
1244 struct bonding *bond = to_bond(d); 1221 struct bonding *bond = to_bond(d);
1245 struct slave *curr; 1222 struct net_device *slave_dev;
1246 int count = 0; 1223 int count = 0;
1247 1224
1248 rcu_read_lock(); 1225 rcu_read_lock();
1249 curr = rcu_dereference(bond->curr_active_slave); 1226 slave_dev = bond_option_active_slave_get_rcu(bond);
1250 if (USES_PRIMARY(bond->params.mode) && curr) 1227 if (slave_dev)
1251 count = sprintf(buf, "%s\n", curr->dev->name); 1228 count = sprintf(buf, "%s\n", slave_dev->name);
1252 rcu_read_unlock(); 1229 rcu_read_unlock();
1253 1230
1254 return count; 1231 return count;
@@ -1258,81 +1235,33 @@ static ssize_t bonding_store_active_slave(struct device *d,
1258 struct device_attribute *attr, 1235 struct device_attribute *attr,
1259 const char *buf, size_t count) 1236 const char *buf, size_t count)
1260{ 1237{
1261 struct slave *slave, *old_active, *new_active; 1238 int ret;
1262 struct bonding *bond = to_bond(d); 1239 struct bonding *bond = to_bond(d);
1263 struct list_head *iter;
1264 char ifname[IFNAMSIZ]; 1240 char ifname[IFNAMSIZ];
1241 struct net_device *dev;
1265 1242
1266 if (!rtnl_trylock()) 1243 if (!rtnl_trylock())
1267 return restart_syscall(); 1244 return restart_syscall();
1268 1245
1269 old_active = new_active = NULL;
1270 block_netpoll_tx();
1271 read_lock(&bond->lock);
1272 write_lock_bh(&bond->curr_slave_lock);
1273
1274 if (!USES_PRIMARY(bond->params.mode)) {
1275 pr_info("%s: Unable to change active slave; %s is in mode %d\n",
1276 bond->dev->name, bond->dev->name, bond->params.mode);
1277 goto out;
1278 }
1279
1280 sscanf(buf, "%15s", ifname); /* IFNAMSIZ */ 1246 sscanf(buf, "%15s", ifname); /* IFNAMSIZ */
1281
1282 /* check to see if we are clearing active */
1283 if (!strlen(ifname) || buf[0] == '\n') { 1247 if (!strlen(ifname) || buf[0] == '\n') {
1284 pr_info("%s: Clearing current active slave.\n", 1248 dev = NULL;
1285 bond->dev->name); 1249 } else {
1286 rcu_assign_pointer(bond->curr_active_slave, NULL); 1250 dev = __dev_get_by_name(dev_net(bond->dev), ifname);
1287 bond_select_active_slave(bond); 1251 if (!dev) {
1288 goto out; 1252 ret = -ENODEV;
1289 } 1253 goto out;
1290
1291 bond_for_each_slave(bond, slave, iter) {
1292 if (strncmp(slave->dev->name, ifname, IFNAMSIZ) == 0) {
1293 old_active = bond->curr_active_slave;
1294 new_active = slave;
1295 if (new_active == old_active) {
1296 /* do nothing */
1297 pr_info("%s: %s is already the current"
1298 " active slave.\n",
1299 bond->dev->name,
1300 slave->dev->name);
1301 goto out;
1302 } else {
1303 if ((new_active) &&
1304 (old_active) &&
1305 (new_active->link == BOND_LINK_UP) &&
1306 IS_UP(new_active->dev)) {
1307 pr_info("%s: Setting %s as active"
1308 " slave.\n",
1309 bond->dev->name,
1310 slave->dev->name);
1311 bond_change_active_slave(bond,
1312 new_active);
1313 } else {
1314 pr_info("%s: Could not set %s as"
1315 " active slave; either %s is"
1316 " down or the link is down.\n",
1317 bond->dev->name,
1318 slave->dev->name,
1319 slave->dev->name);
1320 }
1321 goto out;
1322 }
1323 } 1254 }
1324 } 1255 }
1325 1256
1326 pr_info("%s: Unable to set %.*s as active slave.\n", 1257 ret = bond_option_active_slave_set(bond, dev);
1327 bond->dev->name, (int)strlen(buf) - 1, buf); 1258 if (!ret)
1328 out: 1259 ret = count;
1329 write_unlock_bh(&bond->curr_slave_lock);
1330 read_unlock(&bond->lock);
1331 unblock_netpoll_tx();
1332 1260
1261 out:
1333 rtnl_unlock(); 1262 rtnl_unlock();
1334 1263
1335 return count; 1264 return ret;
1336 1265
1337} 1266}
1338static DEVICE_ATTR(active_slave, S_IRUGO | S_IWUSR, 1267static DEVICE_ATTR(active_slave, S_IRUGO | S_IWUSR,
diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h
index bb5c731e2560..046a60535e04 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)
@@ -418,6 +422,14 @@ void bond_debug_register(struct bonding *bond);
418void bond_debug_unregister(struct bonding *bond); 422void bond_debug_unregister(struct bonding *bond);
419void bond_debug_reregister(struct bonding *bond); 423void bond_debug_reregister(struct bonding *bond);
420const char *bond_mode_name(int mode); 424const char *bond_mode_name(int mode);
425void bond_setup(struct net_device *bond_dev);
426unsigned int bond_get_num_tx_queues(void);
427int bond_netlink_init(void);
428void bond_netlink_fini(void);
429int bond_option_mode_set(struct bonding *bond, int mode);
430int bond_option_active_slave_set(struct bonding *bond, struct net_device *slave_dev);
431struct net_device *bond_option_active_slave_get_rcu(struct bonding *bond);
432struct net_device *bond_option_active_slave_get(struct bonding *bond);
421 433
422struct bond_net { 434struct bond_net {
423 struct net * net; /* Associated network namespace */ 435 struct net * net; /* Associated network namespace */
@@ -505,4 +517,7 @@ extern const struct bond_parm_tbl fail_over_mac_tbl[];
505extern const struct bond_parm_tbl pri_reselect_tbl[]; 517extern const struct bond_parm_tbl pri_reselect_tbl[];
506extern struct bond_parm_tbl ad_select_tbl[]; 518extern struct bond_parm_tbl ad_select_tbl[];
507 519
520/* exported from bond_netlink.c */
521extern struct rtnl_link_ops bond_link_ops;
522
508#endif /* _LINUX_BONDING_H */ 523#endif /* _LINUX_BONDING_H */
diff --git a/include/uapi/linux/if_link.h b/include/uapi/linux/if_link.h
index 80394e8dc3a3..8a1e346243b7 100644
--- a/include/uapi/linux/if_link.h
+++ b/include/uapi/linux/if_link.h
@@ -325,6 +325,17 @@ struct ifla_vxlan_port_range {
325 __be16 high; 325 __be16 high;
326}; 326};
327 327
328/* Bonding section */
329
330enum {
331 IFLA_BOND_UNSPEC,
332 IFLA_BOND_MODE,
333 IFLA_BOND_ACTIVE_SLAVE,
334 __IFLA_BOND_MAX,
335};
336
337#define IFLA_BOND_MAX (__IFLA_BOND_MAX - 1)
338
328/* SR-IOV virtual function management section */ 339/* SR-IOV virtual function management section */
329 340
330enum { 341enum {