aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/bonding
diff options
context:
space:
mode:
authorMitch Williams <mitch.a.williams@intel.com>2005-11-09 13:36:41 -0500
committerJohn W. Linville <linville@tuxdriver.com>2005-11-13 14:48:21 -0500
commitb76cdba9cdb29b091cacb4c11534ffb2eac02f64 (patch)
treea9125448834fd8daf6ae50bfa376d6a6ee697425 /drivers/net/bonding
parent4756b02f558cbbbef5ae278fd3bbed778458c124 (diff)
[PATCH] bonding: add sysfs functionality to bonding (large)
This large patch adds sysfs functionality to the channel bonding module. Bonds can be added, removed, and reconfigured at runtime without having to reload the module. Multiple bonds with different configurations are easily configured, and ifenslave is no longer required to configure bonds. Signed-off-by: Mitch Williams <mitch.a.williams@intel.com> Acked-by: Jay Vosburgh <fubar@us.ibm.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/bonding')
-rw-r--r--drivers/net/bonding/Makefile2
-rw-r--r--drivers/net/bonding/bond_main.c23
-rw-r--r--drivers/net/bonding/bond_sysfs.c1399
-rw-r--r--drivers/net/bonding/bonding.h7
4 files changed, 1429 insertions, 2 deletions
diff --git a/drivers/net/bonding/Makefile b/drivers/net/bonding/Makefile
index cf50384b469e..5cdae2bc055a 100644
--- a/drivers/net/bonding/Makefile
+++ b/drivers/net/bonding/Makefile
@@ -4,5 +4,5 @@
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 7bonding-objs := bond_main.o bond_3ad.o bond_alb.o bond_sysfs.o
8 8
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index d5415ba9bdb0..5ac9718c5988 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -600,6 +600,7 @@ LIST_HEAD(bond_dev_list);
600static struct proc_dir_entry *bond_proc_dir = NULL; 600static struct proc_dir_entry *bond_proc_dir = NULL;
601#endif 601#endif
602 602
603extern struct rw_semaphore bonding_rwsem;
603static u32 arp_target[BOND_MAX_ARP_TARGETS] = { 0, } ; 604static u32 arp_target[BOND_MAX_ARP_TARGETS] = { 0, } ;
604static int arp_ip_count = 0; 605static int arp_ip_count = 0;
605static int bond_mode = BOND_MODE_ROUNDROBIN; 606static int bond_mode = BOND_MODE_ROUNDROBIN;
@@ -1960,6 +1961,10 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
1960 1961
1961 write_unlock_bh(&bond->lock); 1962 write_unlock_bh(&bond->lock);
1962 1963
1964 res = bond_create_slave_symlinks(bond_dev, slave_dev);
1965 if (res)
1966 goto err_unset_master;
1967
1963 printk(KERN_INFO DRV_NAME 1968 printk(KERN_INFO DRV_NAME
1964 ": %s: enslaving %s as a%s interface with a%s link.\n", 1969 ": %s: enslaving %s as a%s interface with a%s link.\n",
1965 bond_dev->name, slave_dev->name, 1970 bond_dev->name, slave_dev->name,
@@ -2133,6 +2138,9 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev)
2133 2138
2134 write_unlock_bh(&bond->lock); 2139 write_unlock_bh(&bond->lock);
2135 2140
2141 /* must do this from outside any spinlocks */
2142 bond_destroy_slave_symlinks(bond_dev, slave_dev);
2143
2136 bond_del_vlans_from_slave(bond, slave_dev); 2144 bond_del_vlans_from_slave(bond, slave_dev);
2137 2145
2138 /* If the mode USES_PRIMARY, then we should only remove its 2146 /* If the mode USES_PRIMARY, then we should only remove its
@@ -2224,6 +2232,7 @@ static int bond_release_all(struct net_device *bond_dev)
2224 */ 2232 */
2225 write_unlock_bh(&bond->lock); 2233 write_unlock_bh(&bond->lock);
2226 2234
2235 bond_destroy_slave_symlinks(bond_dev, slave_dev);
2227 bond_del_vlans_from_slave(bond, slave_dev); 2236 bond_del_vlans_from_slave(bond, slave_dev);
2228 2237
2229 /* If the mode USES_PRIMARY, then we should only remove its 2238 /* If the mode USES_PRIMARY, then we should only remove its
@@ -3518,7 +3527,10 @@ static int bond_event_changename(struct bonding *bond)
3518 bond_remove_proc_entry(bond); 3527 bond_remove_proc_entry(bond);
3519 bond_create_proc_entry(bond); 3528 bond_create_proc_entry(bond);
3520#endif 3529#endif
3521 3530 down_write(&(bonding_rwsem));
3531 bond_destroy_sysfs_entry(bond);
3532 bond_create_sysfs_entry(bond);
3533 up_write(&(bonding_rwsem));
3522 return NOTIFY_DONE; 3534 return NOTIFY_DONE;
3523} 3535}
3524 3536
@@ -3995,6 +4007,7 @@ static int bond_do_ioctl(struct net_device *bond_dev, struct ifreq *ifr, int cmd
3995 return -EPERM; 4007 return -EPERM;
3996 } 4008 }
3997 4009
4010 down_write(&(bonding_rwsem));
3998 slave_dev = dev_get_by_name(ifr->ifr_slave); 4011 slave_dev = dev_get_by_name(ifr->ifr_slave);
3999 4012
4000 dprintk("slave_dev=%p: \n", slave_dev); 4013 dprintk("slave_dev=%p: \n", slave_dev);
@@ -4027,6 +4040,7 @@ static int bond_do_ioctl(struct net_device *bond_dev, struct ifreq *ifr, int cmd
4027 dev_put(slave_dev); 4040 dev_put(slave_dev);
4028 } 4041 }
4029 4042
4043 up_write(&(bonding_rwsem));
4030 return res; 4044 return res;
4031} 4045}
4032 4046
@@ -4962,6 +4976,7 @@ int bond_create(char *name, struct bond_params *params, struct bonding **newbond
4962 *newbond = bond_dev->priv; 4976 *newbond = bond_dev->priv;
4963 4977
4964 rtnl_unlock(); /* allows sysfs registration of net device */ 4978 rtnl_unlock(); /* allows sysfs registration of net device */
4979 res = bond_create_sysfs_entry(bond_dev->priv);
4965 goto done; 4980 goto done;
4966out_bond: 4981out_bond:
4967 bond_deinit(bond_dev); 4982 bond_deinit(bond_dev);
@@ -4996,6 +5011,10 @@ static int __init bonding_init(void)
4996 goto err; 5011 goto err;
4997 } 5012 }
4998 5013
5014 res = bond_create_sysfs();
5015 if (res)
5016 goto err;
5017
4999 register_netdevice_notifier(&bond_netdev_notifier); 5018 register_netdevice_notifier(&bond_netdev_notifier);
5000 register_inetaddr_notifier(&bond_inetaddr_notifier); 5019 register_inetaddr_notifier(&bond_inetaddr_notifier);
5001 5020
@@ -5003,6 +5022,7 @@ static int __init bonding_init(void)
5003err: 5022err:
5004 rtnl_lock(); 5023 rtnl_lock();
5005 bond_free_all(); 5024 bond_free_all();
5025 bond_destroy_sysfs();
5006 rtnl_unlock(); 5026 rtnl_unlock();
5007out: 5027out:
5008 return res; 5028 return res;
@@ -5016,6 +5036,7 @@ static void __exit bonding_exit(void)
5016 5036
5017 rtnl_lock(); 5037 rtnl_lock();
5018 bond_free_all(); 5038 bond_free_all();
5039 bond_destroy_sysfs();
5019 rtnl_unlock(); 5040 rtnl_unlock();
5020} 5041}
5021 5042
diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c
new file mode 100644
index 000000000000..c5f1c52863cb
--- /dev/null
+++ b/drivers/net/bonding/bond_sysfs.c
@@ -0,0 +1,1399 @@
1
2/*
3 * Copyright(c) 2004-2005 Intel Corporation. All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 * for more details.
14 *
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18 *
19 * The full GNU General Public License is included in this distribution in the
20 * file called LICENSE.
21 *
22 *
23 * Changes:
24 *
25 * 2004/12/12 - Mitch Williams <mitch.a.williams at intel dot com>
26 * - Initial creation of sysfs interface.
27 *
28 * 2005/06/22 - Radheka Godse <radheka.godse at intel dot com>
29 * - Added ifenslave -c type functionality to sysfs
30 * - Added sysfs files for attributes such as MII Status and
31 * 802.3ad aggregator that are displayed in /proc
32 * - Added "name value" format to sysfs "mode" and
33 * "lacp_rate", for e.g., "active-backup 1" or "slow 0" for
34 * consistency and ease of script parsing
35 * - Fixed reversal of octets in arp_ip_targets via sysfs
36 * - sysfs support to handle bond interface re-naming
37 * - Moved all sysfs entries into /sys/class/net instead of
38 * of using a standalone subsystem.
39 * - Added sysfs symlinks between masters and slaves
40 * - Corrected bugs in sysfs unload path when creating bonds
41 * with existing interface names.
42 * - Removed redundant sysfs stat file since it duplicates slave info
43 * from the proc file
44 * - Fixed errors in sysfs show/store arp targets.
45 * - For consistency with ifenslave, instead of exiting
46 * with an error, updated bonding sysfs to
47 * close and attempt to enslave an up adapter.
48 * - Fixed NULL dereference when adding a slave interface
49 * that does not exist.
50 * - Added checks in sysfs bonding to reject invalid ip addresses
51 * - Synch up with post linux-2.6.12 bonding changes
52 * - Created sysfs bond attrib for xmit_hash_policy
53 *
54 * 2005/09/19 - Mitch Williams <mitch.a.williams at intel dot com>
55 * - Changed semantics of multi-item files to be command-based
56 * instead of list-based.
57 * - Changed ARP target handler to use in_aton instead of sscanf
58 * - Style changes.
59 * 2005/09/27 - Mitch Williams <mitch.a.williams at intel dot com>
60 * - Made line endings consistent.
61 * - Removed "none" from primary output - just put blank instead
62 * - Fixed bug with long interface names
63 */
64#include <linux/config.h>
65#include <linux/kernel.h>
66#include <linux/module.h>
67#include <linux/sched.h>
68#include <linux/device.h>
69#include <linux/sysdev.h>
70#include <linux/fs.h>
71#include <linux/types.h>
72#include <linux/string.h>
73#include <linux/netdevice.h>
74#include <linux/inetdevice.h>
75#include <linux/in.h>
76#include <linux/sysfs.h>
77#include <linux/string.h>
78#include <linux/ctype.h>
79#include <linux/inet.h>
80#include <linux/rtnetlink.h>
81
82/* #define BONDING_DEBUG 1 */
83#include "bonding.h"
84#define to_class_dev(obj) container_of(obj,struct class_device,kobj)
85#define to_net_dev(class) container_of(class, struct net_device, class_dev)
86#define to_bond(cd) ((struct bonding *)(to_net_dev(cd)->priv))
87
88/*---------------------------- Declarations -------------------------------*/
89
90
91extern struct list_head bond_dev_list;
92extern struct bond_params bonding_defaults;
93extern struct bond_parm_tbl bond_mode_tbl[];
94extern struct bond_parm_tbl bond_lacp_tbl[];
95extern struct bond_parm_tbl xmit_hashtype_tbl[];
96
97static int expected_refcount = -1;
98static struct class *netdev_class;
99/*--------------------------- Data Structures -----------------------------*/
100
101/* Bonding sysfs lock. Why can't we just use the subsytem lock?
102 * Because kobject_register tries to acquire the subsystem lock. If
103 * we already hold the lock (which we would if the user was creating
104 * a new bond through the sysfs interface), we deadlock.
105 * This lock is only needed when deleting a bond - we need to make sure
106 * that we don't collide with an ongoing ioctl.
107 */
108
109struct rw_semaphore bonding_rwsem;
110
111
112
113
114/*------------------------------ Functions --------------------------------*/
115
116/*
117 * "show" function for the bond_masters attribute.
118 * The class parameter is ignored.
119 */
120static ssize_t bonding_show_bonds(struct class *cls, char *buffer)
121{
122 int res = 0;
123 struct bonding *bond;
124
125 down_read(&(bonding_rwsem));
126
127 list_for_each_entry(bond, &bond_dev_list, bond_list) {
128 if (res > (PAGE_SIZE - IFNAMSIZ)) {
129 /* not enough space for another interface name */
130 if ((PAGE_SIZE - res) > 10)
131 res = PAGE_SIZE - 10;
132 res += sprintf(buffer + res, "++more++");
133 break;
134 }
135 res += sprintf(buffer + res, "%s ",
136 bond->dev->name);
137 }
138 res += sprintf(buffer + res, "\n");
139 res++;
140 up_read(&(bonding_rwsem));
141 return res;
142}
143
144/*
145 * "store" function for the bond_masters attribute. This is what
146 * creates and deletes entire bonds.
147 *
148 * The class parameter is ignored.
149 *
150 */
151
152static ssize_t bonding_store_bonds(struct class *cls, const char *buffer, size_t count)
153{
154 char command[IFNAMSIZ + 1] = {0, };
155 char *ifname;
156 int res = count;
157 struct bonding *bond;
158 struct bonding *nxt;
159
160 down_write(&(bonding_rwsem));
161 sscanf(buffer, "%16s", command); /* IFNAMSIZ*/
162 ifname = command + 1;
163 if ((strlen(command) <= 1) ||
164 !dev_valid_name(ifname))
165 goto err_no_cmd;
166
167 if (command[0] == '+') {
168
169 /* Check to see if the bond already exists. */
170 list_for_each_entry_safe(bond, nxt, &bond_dev_list, bond_list)
171 if (strnicmp(bond->dev->name, ifname, IFNAMSIZ) == 0) {
172 printk(KERN_ERR DRV_NAME
173 ": cannot add bond %s; it already exists\n",
174 ifname);
175 res = -EPERM;
176 goto out;
177 }
178
179 printk(KERN_INFO DRV_NAME
180 ": %s is being created...\n", ifname);
181 if (bond_create(ifname, &bonding_defaults, &bond)) {
182 printk(KERN_INFO DRV_NAME
183 ": %s interface already exists. Bond creation failed.\n",
184 ifname);
185 res = -EPERM;
186 }
187 goto out;
188 }
189
190 if (command[0] == '-') {
191 list_for_each_entry_safe(bond, nxt, &bond_dev_list, bond_list)
192 if (strnicmp(bond->dev->name, ifname, IFNAMSIZ) == 0) {
193 rtnl_lock();
194 /* check the ref count on the bond's kobject.
195 * If it's > expected, then there's a file open,
196 * and we have to fail.
197 */
198 if (atomic_read(&bond->dev->class_dev.kobj.kref.refcount)
199 > expected_refcount){
200 rtnl_unlock();
201 printk(KERN_INFO DRV_NAME
202 ": Unable remove bond %s due to open references.\n",
203 ifname);
204 res = -EPERM;
205 goto out;
206 }
207 printk(KERN_INFO DRV_NAME
208 ": %s is being deleted...\n",
209 bond->dev->name);
210 unregister_netdevice(bond->dev);
211 bond_deinit(bond->dev);
212 bond_destroy_sysfs_entry(bond);
213 rtnl_unlock();
214 goto out;
215 }
216
217 printk(KERN_ERR DRV_NAME
218 ": unable to delete non-existent bond %s\n", ifname);
219 res = -ENODEV;
220 goto out;
221 }
222
223err_no_cmd:
224 printk(KERN_ERR DRV_NAME
225 ": no command found in bonding_masters. Use +ifname or -ifname.\n");
226 res = -EPERM;
227
228 /* Always return either count or an error. If you return 0, you'll
229 * get called forever, which is bad.
230 */
231out:
232 up_write(&(bonding_rwsem));
233 return res;
234}
235/* class attribute for bond_masters file. This ends up in /sys/class/net */
236static CLASS_ATTR(bonding_masters, S_IWUSR | S_IRUGO,
237 bonding_show_bonds, bonding_store_bonds);
238
239int bond_create_slave_symlinks(struct net_device *master, struct net_device *slave)
240{
241 char linkname[IFNAMSIZ+7];
242 int ret = 0;
243
244 /* first, create a link from the slave back to the master */
245 ret = sysfs_create_link(&(slave->class_dev.kobj), &(master->class_dev.kobj),
246 "master");
247 if (ret)
248 return ret;
249 /* next, create a link from the master to the slave */
250 sprintf(linkname,"slave_%s",slave->name);
251 ret = sysfs_create_link(&(master->class_dev.kobj), &(slave->class_dev.kobj),
252 linkname);
253 return ret;
254
255}
256
257void bond_destroy_slave_symlinks(struct net_device *master, struct net_device *slave)
258{
259 char linkname[IFNAMSIZ+7];
260
261 sysfs_remove_link(&(slave->class_dev.kobj), "master");
262 sprintf(linkname,"slave_%s",slave->name);
263 sysfs_remove_link(&(master->class_dev.kobj), linkname);
264}
265
266
267/*
268 * Show the slaves in the current bond.
269 */
270static ssize_t bonding_show_slaves(struct class_device *cd, char *buf)
271{
272 struct slave *slave;
273 int i, res = 0;
274 struct bonding *bond = to_bond(cd);
275
276 read_lock_bh(&bond->lock);
277 bond_for_each_slave(bond, slave, i) {
278 if (res > (PAGE_SIZE - IFNAMSIZ)) {
279 /* not enough space for another interface name */
280 if ((PAGE_SIZE - res) > 10)
281 res = PAGE_SIZE - 10;
282 res += sprintf(buf + res, "++more++");
283 break;
284 }
285 res += sprintf(buf + res, "%s ", slave->dev->name);
286 }
287 read_unlock_bh(&bond->lock);
288 res += sprintf(buf + res, "\n");
289 res++;
290 return res;
291}
292
293/*
294 * Set the slaves in the current bond. The bond interface must be
295 * up for this to succeed.
296 * This function is largely the same flow as bonding_update_bonds().
297 */
298static ssize_t bonding_store_slaves(struct class_device *cd, const char *buffer, size_t count)
299{
300 char command[IFNAMSIZ + 1] = { 0, };
301 char *ifname;
302 int i, res, found, ret = count;
303 struct slave *slave;
304 struct net_device *dev = 0;
305 struct bonding *bond = to_bond(cd);
306
307 /* Quick sanity check -- is the bond interface up? */
308 if (!(bond->dev->flags & IFF_UP)) {
309 printk(KERN_ERR DRV_NAME
310 ": %s: Unable to update slaves because interface is down.\n",
311 bond->dev->name);
312 ret = -EPERM;
313 goto out;
314 }
315
316 /* Note: We can't hold bond->lock here, as bond_create grabs it. */
317
318 sscanf(buffer, "%16s", command); /* IFNAMSIZ*/
319 ifname = command + 1;
320 if ((strlen(command) <= 1) ||
321 !dev_valid_name(ifname))
322 goto err_no_cmd;
323
324 if (command[0] == '+') {
325
326 /* Got a slave name in ifname. Is it already in the list? */
327 found = 0;
328 read_lock_bh(&bond->lock);
329 bond_for_each_slave(bond, slave, i)
330 if (strnicmp(slave->dev->name, ifname, IFNAMSIZ) == 0) {
331 printk(KERN_ERR DRV_NAME
332 ": %s: Interface %s is already enslaved!\n",
333 bond->dev->name, ifname);
334 ret = -EPERM;
335 read_unlock_bh(&bond->lock);
336 goto out;
337 }
338
339 read_unlock_bh(&bond->lock);
340 printk(KERN_INFO DRV_NAME ": %s: Adding slave %s.\n",
341 bond->dev->name, ifname);
342 dev = dev_get_by_name(ifname);
343 if (!dev) {
344 printk(KERN_INFO DRV_NAME
345 ": %s: Interface %s does not exist!\n",
346 bond->dev->name, ifname);
347 ret = -EPERM;
348 goto out;
349 }
350 else
351 dev_put(dev);
352
353 if (dev->flags & IFF_UP) {
354 printk(KERN_ERR DRV_NAME
355 ": %s: Error: Unable to enslave %s "
356 "because it is already up.\n",
357 bond->dev->name, dev->name);
358 ret = -EPERM;
359 goto out;
360 }
361 /* If this is the first slave, then we need to set
362 the master's hardware address to be the same as the
363 slave's. */
364 if (!(*((u32 *) & (bond->dev->dev_addr[0])))) {
365 memcpy(bond->dev->dev_addr, dev->dev_addr,
366 dev->addr_len);
367 }
368
369 /* Set the slave's MTU to match the bond */
370 if (dev->mtu != bond->dev->mtu) {
371 if (dev->change_mtu) {
372 res = dev->change_mtu(dev,
373 bond->dev->mtu);
374 if (res) {
375 ret = res;
376 goto out;
377 }
378 } else {
379 dev->mtu = bond->dev->mtu;
380 }
381 }
382 rtnl_lock();
383 res = bond_enslave(bond->dev, dev);
384 rtnl_unlock();
385 if (res) {
386 ret = res;
387 }
388 goto out;
389 }
390
391 if (command[0] == '-') {
392 dev = NULL;
393 bond_for_each_slave(bond, slave, i)
394 if (strnicmp(slave->dev->name, ifname, IFNAMSIZ) == 0) {
395 dev = slave->dev;
396 break;
397 }
398 if (dev) {
399 printk(KERN_INFO DRV_NAME ": %s: Removing slave %s\n",
400 bond->dev->name, dev->name);
401 rtnl_lock();
402 res = bond_release(bond->dev, dev);
403 rtnl_unlock();
404 if (res) {
405 ret = res;
406 goto out;
407 }
408 /* set the slave MTU to the default */
409 if (dev->change_mtu) {
410 dev->change_mtu(dev, 1500);
411 } else {
412 dev->mtu = 1500;
413 }
414 }
415 else {
416 printk(KERN_ERR DRV_NAME ": unable to remove non-existent slave %s for bond %s.\n",
417 ifname, bond->dev->name);
418 ret = -ENODEV;
419 }
420 goto out;
421 }
422
423err_no_cmd:
424 printk(KERN_ERR DRV_NAME ": no command found in slaves file for bond %s. Use +ifname or -ifname.\n", bond->dev->name);
425 ret = -EPERM;
426
427out:
428 return ret;
429}
430
431static CLASS_DEVICE_ATTR(slaves, S_IRUGO | S_IWUSR, bonding_show_slaves, bonding_store_slaves);
432
433/*
434 * Show and set the bonding mode. The bond interface must be down to
435 * change the mode.
436 */
437static ssize_t bonding_show_mode(struct class_device *cd, char *buf)
438{
439 struct bonding *bond = to_bond(cd);
440
441 return sprintf(buf, "%s %d\n",
442 bond_mode_tbl[bond->params.mode].modename,
443 bond->params.mode) + 1;
444}
445
446static ssize_t bonding_store_mode(struct class_device *cd, const char *buf, size_t count)
447{
448 int new_value, ret = count;
449 struct bonding *bond = to_bond(cd);
450
451 if (bond->dev->flags & IFF_UP) {
452 printk(KERN_ERR DRV_NAME
453 ": unable to update mode of %s because interface is up.\n",
454 bond->dev->name);
455 ret = -EPERM;
456 goto out;
457 }
458
459 new_value = bond_parse_parm((char *)buf, bond_mode_tbl);
460 if (new_value < 0) {
461 printk(KERN_ERR DRV_NAME
462 ": %s: Ignoring invalid mode value %.*s.\n",
463 bond->dev->name,
464 (int)strlen(buf) - 1, buf);
465 ret = -EINVAL;
466 goto out;
467 } else {
468 bond->params.mode = new_value;
469 bond_set_mode_ops(bond, bond->params.mode);
470 printk(KERN_INFO DRV_NAME ": %s: setting mode to %s (%d).\n",
471 bond->dev->name, bond_mode_tbl[new_value].modename, new_value);
472 }
473out:
474 return ret;
475}
476static CLASS_DEVICE_ATTR(mode, S_IRUGO | S_IWUSR, bonding_show_mode, bonding_store_mode);
477
478/*
479 * Show and set the bonding transmit hash method. The bond interface must be down to
480 * change the xmit hash policy.
481 */
482static ssize_t bonding_show_xmit_hash(struct class_device *cd, char *buf)
483{
484 int count;
485 struct bonding *bond = to_bond(cd);
486
487 if ((bond->params.mode != BOND_MODE_XOR) &&
488 (bond->params.mode != BOND_MODE_8023AD)) {
489 // Not Applicable
490 count = sprintf(buf, "NA\n") + 1;
491 } else {
492 count = sprintf(buf, "%s %d\n",
493 xmit_hashtype_tbl[bond->params.xmit_policy].modename,
494 bond->params.xmit_policy) + 1;
495 }
496
497 return count;
498}
499
500static ssize_t bonding_store_xmit_hash(struct class_device *cd, const char *buf, size_t count)
501{
502 int new_value, ret = count;
503 struct bonding *bond = to_bond(cd);
504
505 if (bond->dev->flags & IFF_UP) {
506 printk(KERN_ERR DRV_NAME
507 "%s: Interface is up. Unable to update xmit policy.\n",
508 bond->dev->name);
509 ret = -EPERM;
510 goto out;
511 }
512
513 if ((bond->params.mode != BOND_MODE_XOR) &&
514 (bond->params.mode != BOND_MODE_8023AD)) {
515 printk(KERN_ERR DRV_NAME
516 "%s: Transmit hash policy is irrelevant in this mode.\n",
517 bond->dev->name);
518 ret = -EPERM;
519 goto out;
520 }
521
522 new_value = bond_parse_parm((char *)buf, xmit_hashtype_tbl);
523 if (new_value < 0) {
524 printk(KERN_ERR DRV_NAME
525 ": %s: Ignoring invalid xmit hash policy value %.*s.\n",
526 bond->dev->name,
527 (int)strlen(buf) - 1, buf);
528 ret = -EINVAL;
529 goto out;
530 } else {
531 bond->params.xmit_policy = new_value;
532 bond_set_mode_ops(bond, bond->params.mode);
533 printk(KERN_INFO DRV_NAME ": %s: setting xmit hash policy to %s (%d).\n",
534 bond->dev->name, xmit_hashtype_tbl[new_value].modename, new_value);
535 }
536out:
537 return ret;
538}
539static CLASS_DEVICE_ATTR(xmit_hash_policy, S_IRUGO | S_IWUSR, bonding_show_xmit_hash, bonding_store_xmit_hash);
540
541/*
542 * Show and set the arp timer interval. There are two tricky bits
543 * here. First, if ARP monitoring is activated, then we must disable
544 * MII monitoring. Second, if the ARP timer isn't running, we must
545 * start it.
546 */
547static ssize_t bonding_show_arp_interval(struct class_device *cd, char *buf)
548{
549 struct bonding *bond = to_bond(cd);
550
551 return sprintf(buf, "%d\n", bond->params.arp_interval) + 1;
552}
553
554static ssize_t bonding_store_arp_interval(struct class_device *cd, const char *buf, size_t count)
555{
556 int new_value, ret = count;
557 struct bonding *bond = to_bond(cd);
558
559 if (sscanf(buf, "%d", &new_value) != 1) {
560 printk(KERN_ERR DRV_NAME
561 ": %s: no arp_interval value specified.\n",
562 bond->dev->name);
563 ret = -EINVAL;
564 goto out;
565 }
566 if (new_value < 0) {
567 printk(KERN_ERR DRV_NAME
568 ": %s: Invalid arp_interval value %d not in range 1-%d; rejected.\n",
569 bond->dev->name, new_value, INT_MAX);
570 ret = -EINVAL;
571 goto out;
572 }
573
574 printk(KERN_INFO DRV_NAME
575 ": %s: Setting ARP monitoring interval to %d.\n",
576 bond->dev->name, new_value);
577 bond->params.arp_interval = new_value;
578 if (bond->params.miimon) {
579 printk(KERN_INFO DRV_NAME
580 ": %s: ARP monitoring cannot be used with MII monitoring. "
581 "%s Disabling MII monitoring.\n",
582 bond->dev->name, bond->dev->name);
583 bond->params.miimon = 0;
584 /* Kill MII timer, else it brings bond's link down */
585 if (bond->arp_timer.function) {
586 printk(KERN_INFO DRV_NAME
587 ": %s: Kill MII timer, else it brings bond's link down...\n",
588 bond->dev->name);
589 del_timer_sync(&bond->mii_timer);
590 }
591 }
592 if (!bond->params.arp_targets[0]) {
593 printk(KERN_INFO DRV_NAME
594 ": %s: ARP monitoring has been set up, "
595 "but no ARP targets have been specified.\n",
596 bond->dev->name);
597 }
598 if (bond->dev->flags & IFF_UP) {
599 /* If the interface is up, we may need to fire off
600 * the ARP timer. If the interface is down, the
601 * timer will get fired off when the open function
602 * is called.
603 */
604 if (bond->arp_timer.function) {
605 /* The timer's already set up, so fire it off */
606 mod_timer(&bond->arp_timer, jiffies + 1);
607 } else {
608 /* Set up the timer. */
609 init_timer(&bond->arp_timer);
610 bond->arp_timer.expires = jiffies + 1;
611 bond->arp_timer.data =
612 (unsigned long) bond->dev;
613 if (bond->params.mode == BOND_MODE_ACTIVEBACKUP) {
614 bond->arp_timer.function =
615 (void *)
616 &bond_activebackup_arp_mon;
617 } else {
618 bond->arp_timer.function =
619 (void *)
620 &bond_loadbalance_arp_mon;
621 }
622 add_timer(&bond->arp_timer);
623 }
624 }
625
626out:
627 return ret;
628}
629static CLASS_DEVICE_ATTR(arp_interval, S_IRUGO | S_IWUSR , bonding_show_arp_interval, bonding_store_arp_interval);
630
631/*
632 * Show and set the arp targets.
633 */
634static ssize_t bonding_show_arp_targets(struct class_device *cd, char *buf)
635{
636 int i, res = 0;
637 struct bonding *bond = to_bond(cd);
638
639 for (i = 0; i < BOND_MAX_ARP_TARGETS; i++) {
640 if (bond->params.arp_targets[i])
641 res += sprintf(buf + res, "%u.%u.%u.%u ",
642 NIPQUAD(bond->params.arp_targets[i]));
643 }
644 if (res)
645 res--; /* eat the leftover space */
646 res += sprintf(buf + res, "\n");
647 res++;
648 return res;
649}
650
651static ssize_t bonding_store_arp_targets(struct class_device *cd, const char *buf, size_t count)
652{
653 u32 newtarget;
654 int i = 0, done = 0, ret = count;
655 struct bonding *bond = to_bond(cd);
656 u32 *targets;
657
658 targets = bond->params.arp_targets;
659 newtarget = in_aton(buf + 1);
660 /* look for adds */
661 if (buf[0] == '+') {
662 if ((newtarget == 0) || (newtarget == INADDR_BROADCAST)) {
663 printk(KERN_ERR DRV_NAME
664 ": %s: invalid ARP target %u.%u.%u.%u specified for addition\n",
665 bond->dev->name, NIPQUAD(newtarget));
666 ret = -EINVAL;
667 goto out;
668 }
669 /* look for an empty slot to put the target in, and check for dupes */
670 for (i = 0; (i < BOND_MAX_ARP_TARGETS); i++) {
671 if (targets[i] == newtarget) { /* duplicate */
672 printk(KERN_ERR DRV_NAME
673 ": %s: ARP target %u.%u.%u.%u is already present\n",
674 bond->dev->name, NIPQUAD(newtarget));
675 if (done)
676 targets[i] = 0;
677 ret = -EINVAL;
678 goto out;
679 }
680 if (targets[i] == 0 && !done) {
681 printk(KERN_INFO DRV_NAME
682 ": %s: adding ARP target %d.%d.%d.%d.\n",
683 bond->dev->name, NIPQUAD(newtarget));
684 done = 1;
685 targets[i] = newtarget;
686 }
687 }
688 if (!done) {
689 printk(KERN_ERR DRV_NAME
690 ": %s: ARP target table is full!\n",
691 bond->dev->name);
692 ret = -EINVAL;
693 goto out;
694 }
695
696 }
697 else if (buf[0] == '-') {
698 if ((newtarget == 0) || (newtarget == INADDR_BROADCAST)) {
699 printk(KERN_ERR DRV_NAME
700 ": %s: invalid ARP target %d.%d.%d.%d specified for removal\n",
701 bond->dev->name, NIPQUAD(newtarget));
702 ret = -EINVAL;
703 goto out;
704 }
705
706 for (i = 0; (i < BOND_MAX_ARP_TARGETS); i++) {
707 if (targets[i] == newtarget) {
708 printk(KERN_INFO DRV_NAME
709 ": %s: removing ARP target %d.%d.%d.%d.\n",
710 bond->dev->name, NIPQUAD(newtarget));
711 targets[i] = 0;
712 done = 1;
713 }
714 }
715 if (!done) {
716 printk(KERN_INFO DRV_NAME
717 ": %s: unable to remove nonexistent ARP target %d.%d.%d.%d.\n",
718 bond->dev->name, NIPQUAD(newtarget));
719 ret = -EINVAL;
720 goto out;
721 }
722 }
723 else {
724 printk(KERN_ERR DRV_NAME ": no command found in arp_ip_targets file for bond %s. Use +<addr> or -<addr>.\n",
725 bond->dev->name);
726 ret = -EPERM;
727 goto out;
728 }
729
730out:
731 return ret;
732}
733static CLASS_DEVICE_ATTR(arp_ip_target, S_IRUGO | S_IWUSR , bonding_show_arp_targets, bonding_store_arp_targets);
734
735/*
736 * Show and set the up and down delays. These must be multiples of the
737 * MII monitoring value, and are stored internally as the multiplier.
738 * Thus, we must translate to MS for the real world.
739 */
740static ssize_t bonding_show_downdelay(struct class_device *cd, char *buf)
741{
742 struct bonding *bond = to_bond(cd);
743
744 return sprintf(buf, "%d\n", bond->params.downdelay * bond->params.miimon) + 1;
745}
746
747static ssize_t bonding_store_downdelay(struct class_device *cd, const char *buf, size_t count)
748{
749 int new_value, ret = count;
750 struct bonding *bond = to_bond(cd);
751
752 if (!(bond->params.miimon)) {
753 printk(KERN_ERR DRV_NAME
754 ": %s: Unable to set down delay as MII monitoring is disabled\n",
755 bond->dev->name);
756 ret = -EPERM;
757 goto out;
758 }
759
760 if (sscanf(buf, "%d", &new_value) != 1) {
761 printk(KERN_ERR DRV_NAME
762 ": %s: no down delay value specified.\n",
763 bond->dev->name);
764 ret = -EINVAL;
765 goto out;
766 }
767 if (new_value < 0) {
768 printk(KERN_ERR DRV_NAME
769 ": %s: Invalid down delay value %d not in range %d-%d; rejected.\n",
770 bond->dev->name, new_value, 1, INT_MAX);
771 ret = -EINVAL;
772 goto out;
773 } else {
774 if ((new_value % bond->params.miimon) != 0) {
775 printk(KERN_WARNING DRV_NAME
776 ": %s: Warning: down delay (%d) is not a multiple "
777 "of miimon (%d), delay rounded to %d ms\n",
778 bond->dev->name, new_value, bond->params.miimon,
779 (new_value / bond->params.miimon) *
780 bond->params.miimon);
781 }
782 bond->params.downdelay = new_value / bond->params.miimon;
783 printk(KERN_INFO DRV_NAME ": %s: Setting down delay to %d.\n",
784 bond->dev->name, bond->params.downdelay * bond->params.miimon);
785
786 }
787
788out:
789 return ret;
790}
791static CLASS_DEVICE_ATTR(downdelay, S_IRUGO | S_IWUSR , bonding_show_downdelay, bonding_store_downdelay);
792
793static ssize_t bonding_show_updelay(struct class_device *cd, char *buf)
794{
795 struct bonding *bond = to_bond(cd);
796
797 return sprintf(buf, "%d\n", bond->params.updelay * bond->params.miimon) + 1;
798
799}
800
801static ssize_t bonding_store_updelay(struct class_device *cd, const char *buf, size_t count)
802{
803 int new_value, ret = count;
804 struct bonding *bond = to_bond(cd);
805
806 if (!(bond->params.miimon)) {
807 printk(KERN_ERR DRV_NAME
808 ": %s: Unable to set up delay as MII monitoring is disabled\n",
809 bond->dev->name);
810 ret = -EPERM;
811 goto out;
812 }
813
814 if (sscanf(buf, "%d", &new_value) != 1) {
815 printk(KERN_ERR DRV_NAME
816 ": %s: no up delay value specified.\n",
817 bond->dev->name);
818 ret = -EINVAL;
819 goto out;
820 }
821 if (new_value < 0) {
822 printk(KERN_ERR DRV_NAME
823 ": %s: Invalid down delay value %d not in range %d-%d; rejected.\n",
824 bond->dev->name, new_value, 1, INT_MAX);
825 ret = -EINVAL;
826 goto out;
827 } else {
828 if ((new_value % bond->params.miimon) != 0) {
829 printk(KERN_WARNING DRV_NAME
830 ": %s: Warning: up delay (%d) is not a multiple "
831 "of miimon (%d), updelay rounded to %d ms\n",
832 bond->dev->name, new_value, bond->params.miimon,
833 (new_value / bond->params.miimon) *
834 bond->params.miimon);
835 }
836 bond->params.updelay = new_value / bond->params.miimon;
837 printk(KERN_INFO DRV_NAME ": %s: Setting up delay to %d.\n",
838 bond->dev->name, bond->params.updelay * bond->params.miimon);
839
840 }
841
842out:
843 return ret;
844}
845static CLASS_DEVICE_ATTR(updelay, S_IRUGO | S_IWUSR , bonding_show_updelay, bonding_store_updelay);
846
847/*
848 * Show and set the LACP interval. Interface must be down, and the mode
849 * must be set to 802.3ad mode.
850 */
851static ssize_t bonding_show_lacp(struct class_device *cd, char *buf)
852{
853 struct bonding *bond = to_bond(cd);
854
855 return sprintf(buf, "%s %d\n",
856 bond_lacp_tbl[bond->params.lacp_fast].modename,
857 bond->params.lacp_fast) + 1;
858}
859
860static ssize_t bonding_store_lacp(struct class_device *cd, const char *buf, size_t count)
861{
862 int new_value, ret = count;
863 struct bonding *bond = to_bond(cd);
864
865 if (bond->dev->flags & IFF_UP) {
866 printk(KERN_ERR DRV_NAME
867 ": %s: Unable to update LACP rate because interface is up.\n",
868 bond->dev->name);
869 ret = -EPERM;
870 goto out;
871 }
872
873 if (bond->params.mode != BOND_MODE_8023AD) {
874 printk(KERN_ERR DRV_NAME
875 ": %s: Unable to update LACP rate because bond is not in 802.3ad mode.\n",
876 bond->dev->name);
877 ret = -EPERM;
878 goto out;
879 }
880
881 new_value = bond_parse_parm((char *)buf, bond_lacp_tbl);
882
883 if ((new_value == 1) || (new_value == 0)) {
884 bond->params.lacp_fast = new_value;
885 printk(KERN_INFO DRV_NAME
886 ": %s: Setting LACP rate to %s (%d).\n",
887 bond->dev->name, bond_lacp_tbl[new_value].modename, new_value);
888 } else {
889 printk(KERN_ERR DRV_NAME
890 ": %s: Ignoring invalid LACP rate value %.*s.\n",
891 bond->dev->name, (int)strlen(buf) - 1, buf);
892 ret = -EINVAL;
893 }
894out:
895 return ret;
896}
897static CLASS_DEVICE_ATTR(lacp_rate, S_IRUGO | S_IWUSR, bonding_show_lacp, bonding_store_lacp);
898
899/*
900 * Show and set the MII monitor interval. There are two tricky bits
901 * here. First, if MII monitoring is activated, then we must disable
902 * ARP monitoring. Second, if the timer isn't running, we must
903 * start it.
904 */
905static ssize_t bonding_show_miimon(struct class_device *cd, char *buf)
906{
907 struct bonding *bond = to_bond(cd);
908
909 return sprintf(buf, "%d\n", bond->params.miimon) + 1;
910}
911
912static ssize_t bonding_store_miimon(struct class_device *cd, const char *buf, size_t count)
913{
914 int new_value, ret = count;
915 struct bonding *bond = to_bond(cd);
916
917 if (sscanf(buf, "%d", &new_value) != 1) {
918 printk(KERN_ERR DRV_NAME
919 ": %s: no miimon value specified.\n",
920 bond->dev->name);
921 ret = -EINVAL;
922 goto out;
923 }
924 if (new_value < 0) {
925 printk(KERN_ERR DRV_NAME
926 ": %s: Invalid miimon value %d not in range %d-%d; rejected.\n",
927 bond->dev->name, new_value, 1, INT_MAX);
928 ret = -EINVAL;
929 goto out;
930 } else {
931 printk(KERN_INFO DRV_NAME
932 ": %s: Setting MII monitoring interval to %d.\n",
933 bond->dev->name, new_value);
934 bond->params.miimon = new_value;
935 if(bond->params.updelay)
936 printk(KERN_INFO DRV_NAME
937 ": %s: Note: Updating updelay (to %d) "
938 "since it is a multiple of the miimon value.\n",
939 bond->dev->name,
940 bond->params.updelay * bond->params.miimon);
941 if(bond->params.downdelay)
942 printk(KERN_INFO DRV_NAME
943 ": %s: Note: Updating downdelay (to %d) "
944 "since it is a multiple of the miimon value.\n",
945 bond->dev->name,
946 bond->params.downdelay * bond->params.miimon);
947 if (bond->params.arp_interval) {
948 printk(KERN_INFO DRV_NAME
949 ": %s: MII monitoring cannot be used with "
950 "ARP monitoring. Disabling ARP monitoring...\n",
951 bond->dev->name);
952 bond->params.arp_interval = 0;
953 /* Kill ARP timer, else it brings bond's link down */
954 if (bond->mii_timer.function) {
955 printk(KERN_INFO DRV_NAME
956 ": %s: Kill ARP timer, else it brings bond's link down...\n",
957 bond->dev->name);
958 del_timer_sync(&bond->arp_timer);
959 }
960 }
961
962 if (bond->dev->flags & IFF_UP) {
963 /* If the interface is up, we may need to fire off
964 * the MII timer. If the interface is down, the
965 * timer will get fired off when the open function
966 * is called.
967 */
968 if (bond->mii_timer.function) {
969 /* The timer's already set up, so fire it off */
970 mod_timer(&bond->mii_timer, jiffies + 1);
971 } else {
972 /* Set up the timer. */
973 init_timer(&bond->mii_timer);
974 bond->mii_timer.expires = jiffies + 1;
975 bond->mii_timer.data =
976 (unsigned long) bond->dev;
977 bond->mii_timer.function =
978 (void *) &bond_mii_monitor;
979 add_timer(&bond->mii_timer);
980 }
981 }
982 }
983out:
984 return ret;
985}
986static CLASS_DEVICE_ATTR(miimon, S_IRUGO | S_IWUSR, bonding_show_miimon, bonding_store_miimon);
987
988/*
989 * Show and set the primary slave. The store function is much
990 * simpler than bonding_store_slaves function because it only needs to
991 * handle one interface name.
992 * The bond must be a mode that supports a primary for this be
993 * set.
994 */
995static ssize_t bonding_show_primary(struct class_device *cd, char *buf)
996{
997 int count = 0;
998 struct bonding *bond = to_bond(cd);
999
1000 if (bond->primary_slave)
1001 count = sprintf(buf, "%s\n", bond->primary_slave->dev->name) + 1;
1002 else
1003 count = sprintf(buf, "\n") + 1;
1004
1005 return count;
1006}
1007
1008static ssize_t bonding_store_primary(struct class_device *cd, const char *buf, size_t count)
1009{
1010 int i;
1011 struct slave *slave;
1012 struct bonding *bond = to_bond(cd);
1013
1014 write_lock_bh(&bond->lock);
1015 if (!USES_PRIMARY(bond->params.mode)) {
1016 printk(KERN_INFO DRV_NAME
1017 ": %s: Unable to set primary slave; %s is in mode %d\n",
1018 bond->dev->name, bond->dev->name, bond->params.mode);
1019 } else {
1020 bond_for_each_slave(bond, slave, i) {
1021 if (strnicmp
1022 (slave->dev->name, buf,
1023 strlen(slave->dev->name)) == 0) {
1024 printk(KERN_INFO DRV_NAME
1025 ": %s: Setting %s as primary slave.\n",
1026 bond->dev->name, slave->dev->name);
1027 bond->primary_slave = slave;
1028 bond_select_active_slave(bond);
1029 goto out;
1030 }
1031 }
1032
1033 /* if we got here, then we didn't match the name of any slave */
1034
1035 if (strlen(buf) == 0 || buf[0] == '\n') {
1036 printk(KERN_INFO DRV_NAME
1037 ": %s: Setting primary slave to None.\n",
1038 bond->dev->name);
1039 bond->primary_slave = 0;
1040 bond_select_active_slave(bond);
1041 } else {
1042 printk(KERN_INFO DRV_NAME
1043 ": %s: Unable to set %.*s as primary slave as it is not a slave.\n",
1044 bond->dev->name, (int)strlen(buf) - 1, buf);
1045 }
1046 }
1047out:
1048 write_unlock_bh(&bond->lock);
1049 return count;
1050}
1051static CLASS_DEVICE_ATTR(primary, S_IRUGO | S_IWUSR, bonding_show_primary, bonding_store_primary);
1052
1053/*
1054 * Show and set the use_carrier flag.
1055 */
1056static ssize_t bonding_show_carrier(struct class_device *cd, char *buf)
1057{
1058 struct bonding *bond = to_bond(cd);
1059
1060 return sprintf(buf, "%d\n", bond->params.use_carrier) + 1;
1061}
1062
1063static ssize_t bonding_store_carrier(struct class_device *cd, const char *buf, size_t count)
1064{
1065 int new_value, ret = count;
1066 struct bonding *bond = to_bond(cd);
1067
1068
1069 if (sscanf(buf, "%d", &new_value) != 1) {
1070 printk(KERN_ERR DRV_NAME
1071 ": %s: no use_carrier value specified.\n",
1072 bond->dev->name);
1073 ret = -EINVAL;
1074 goto out;
1075 }
1076 if ((new_value == 0) || (new_value == 1)) {
1077 bond->params.use_carrier = new_value;
1078 printk(KERN_INFO DRV_NAME ": %s: Setting use_carrier to %d.\n",
1079 bond->dev->name, new_value);
1080 } else {
1081 printk(KERN_INFO DRV_NAME
1082 ": %s: Ignoring invalid use_carrier value %d.\n",
1083 bond->dev->name, new_value);
1084 }
1085out:
1086 return count;
1087}
1088static CLASS_DEVICE_ATTR(use_carrier, S_IRUGO | S_IWUSR, bonding_show_carrier, bonding_store_carrier);
1089
1090
1091/*
1092 * Show and set currently active_slave.
1093 */
1094static ssize_t bonding_show_active_slave(struct class_device *cd, char *buf)
1095{
1096 struct slave *curr;
1097 struct bonding *bond = to_bond(cd);
1098 int count;
1099
1100
1101 read_lock(&bond->curr_slave_lock);
1102 curr = bond->curr_active_slave;
1103 read_unlock(&bond->curr_slave_lock);
1104
1105 if (USES_PRIMARY(bond->params.mode) && curr)
1106 count = sprintf(buf, "%s\n", curr->dev->name) + 1;
1107 else
1108 count = sprintf(buf, "\n") + 1;
1109 return count;
1110}
1111
1112static ssize_t bonding_store_active_slave(struct class_device *cd, const char *buf, size_t count)
1113{
1114 int i;
1115 struct slave *slave;
1116 struct slave *old_active = NULL;
1117 struct slave *new_active = NULL;
1118 struct bonding *bond = to_bond(cd);
1119
1120 write_lock_bh(&bond->lock);
1121 if (!USES_PRIMARY(bond->params.mode)) {
1122 printk(KERN_INFO DRV_NAME
1123 ": %s: Unable to change active slave; %s is in mode %d\n",
1124 bond->dev->name, bond->dev->name, bond->params.mode);
1125 } else {
1126 bond_for_each_slave(bond, slave, i) {
1127 if (strnicmp
1128 (slave->dev->name, buf,
1129 strlen(slave->dev->name)) == 0) {
1130 old_active = bond->curr_active_slave;
1131 new_active = slave;
1132 if (new_active && (new_active == old_active)) {
1133 /* do nothing */
1134 printk(KERN_INFO DRV_NAME
1135 ": %s: %s is already the current active slave.\n",
1136 bond->dev->name, slave->dev->name);
1137 goto out;
1138 }
1139 else {
1140 if ((new_active) &&
1141 (old_active) &&
1142 (new_active->link == BOND_LINK_UP) &&
1143 IS_UP(new_active->dev)) {
1144 printk(KERN_INFO DRV_NAME
1145 ": %s: Setting %s as active slave.\n",
1146 bond->dev->name, slave->dev->name);
1147 bond_change_active_slave(bond, new_active);
1148 }
1149 else {
1150 printk(KERN_INFO DRV_NAME
1151 ": %s: Could not set %s as active slave; "
1152 "either %s is down or the link is down.\n",
1153 bond->dev->name, slave->dev->name,
1154 slave->dev->name);
1155 }
1156 goto out;
1157 }
1158 }
1159 }
1160
1161 /* if we got here, then we didn't match the name of any slave */
1162
1163 if (strlen(buf) == 0 || buf[0] == '\n') {
1164 printk(KERN_INFO DRV_NAME
1165 ": %s: Setting active slave to None.\n",
1166 bond->dev->name);
1167 bond->primary_slave = 0;
1168 bond_select_active_slave(bond);
1169 } else {
1170 printk(KERN_INFO DRV_NAME
1171 ": %s: Unable to set %.*s as active slave as it is not a slave.\n",
1172 bond->dev->name, (int)strlen(buf) - 1, buf);
1173 }
1174 }
1175out:
1176 write_unlock_bh(&bond->lock);
1177 return count;
1178
1179}
1180static CLASS_DEVICE_ATTR(active_slave, S_IRUGO | S_IWUSR, bonding_show_active_slave, bonding_store_active_slave);
1181
1182
1183/*
1184 * Show link status of the bond interface.
1185 */
1186static ssize_t bonding_show_mii_status(struct class_device *cd, char *buf)
1187{
1188 struct slave *curr;
1189 struct bonding *bond = to_bond(cd);
1190
1191 read_lock(&bond->curr_slave_lock);
1192 curr = bond->curr_active_slave;
1193 read_unlock(&bond->curr_slave_lock);
1194
1195 return sprintf(buf, "%s\n", (curr) ? "up" : "down") + 1;
1196}
1197static CLASS_DEVICE_ATTR(mii_status, S_IRUGO, bonding_show_mii_status, NULL);
1198
1199
1200/*
1201 * Show current 802.3ad aggregator ID.
1202 */
1203static ssize_t bonding_show_ad_aggregator(struct class_device *cd, char *buf)
1204{
1205 int count = 0;
1206 struct bonding *bond = to_bond(cd);
1207
1208 if (bond->params.mode == BOND_MODE_8023AD) {
1209 struct ad_info ad_info;
1210 count = sprintf(buf, "%d\n", (bond_3ad_get_active_agg_info(bond, &ad_info)) ? 0 : ad_info.aggregator_id) + 1;
1211 }
1212 else
1213 count = sprintf(buf, "\n") + 1;
1214
1215 return count;
1216}
1217static CLASS_DEVICE_ATTR(ad_aggregator, S_IRUGO, bonding_show_ad_aggregator, NULL);
1218
1219
1220/*
1221 * Show number of active 802.3ad ports.
1222 */
1223static ssize_t bonding_show_ad_num_ports(struct class_device *cd, char *buf)
1224{
1225 int count = 0;
1226 struct bonding *bond = to_bond(cd);
1227
1228 if (bond->params.mode == BOND_MODE_8023AD) {
1229 struct ad_info ad_info;
1230 count = sprintf(buf, "%d\n", (bond_3ad_get_active_agg_info(bond, &ad_info)) ? 0: ad_info.ports) + 1;
1231 }
1232 else
1233 count = sprintf(buf, "\n") + 1;
1234
1235 return count;
1236}
1237static CLASS_DEVICE_ATTR(ad_num_ports, S_IRUGO, bonding_show_ad_num_ports, NULL);
1238
1239
1240/*
1241 * Show current 802.3ad actor key.
1242 */
1243static ssize_t bonding_show_ad_actor_key(struct class_device *cd, char *buf)
1244{
1245 int count = 0;
1246 struct bonding *bond = to_bond(cd);
1247
1248 if (bond->params.mode == BOND_MODE_8023AD) {
1249 struct ad_info ad_info;
1250 count = sprintf(buf, "%d\n", (bond_3ad_get_active_agg_info(bond, &ad_info)) ? 0 : ad_info.actor_key) + 1;
1251 }
1252 else
1253 count = sprintf(buf, "\n") + 1;
1254
1255 return count;
1256}
1257static CLASS_DEVICE_ATTR(ad_actor_key, S_IRUGO, bonding_show_ad_actor_key, NULL);
1258
1259
1260/*
1261 * Show current 802.3ad partner key.
1262 */
1263static ssize_t bonding_show_ad_partner_key(struct class_device *cd, char *buf)
1264{
1265 int count = 0;
1266 struct bonding *bond = to_bond(cd);
1267
1268 if (bond->params.mode == BOND_MODE_8023AD) {
1269 struct ad_info ad_info;
1270 count = sprintf(buf, "%d\n", (bond_3ad_get_active_agg_info(bond, &ad_info)) ? 0 : ad_info.partner_key) + 1;
1271 }
1272 else
1273 count = sprintf(buf, "\n") + 1;
1274
1275 return count;
1276}
1277static CLASS_DEVICE_ATTR(ad_partner_key, S_IRUGO, bonding_show_ad_partner_key, NULL);
1278
1279
1280/*
1281 * Show current 802.3ad partner mac.
1282 */
1283static ssize_t bonding_show_ad_partner_mac(struct class_device *cd, char *buf)
1284{
1285 int count = 0;
1286 struct bonding *bond = to_bond(cd);
1287
1288 if (bond->params.mode == BOND_MODE_8023AD) {
1289 struct ad_info ad_info;
1290 if (!bond_3ad_get_active_agg_info(bond, &ad_info)) {
1291 count = sprintf(buf,"%02x:%02x:%02x:%02x:%02x:%02x\n",
1292 ad_info.partner_system[0],
1293 ad_info.partner_system[1],
1294 ad_info.partner_system[2],
1295 ad_info.partner_system[3],
1296 ad_info.partner_system[4],
1297 ad_info.partner_system[5]) + 1;
1298 }
1299 }
1300 else
1301 count = sprintf(buf, "\n") + 1;
1302
1303 return count;
1304}
1305static CLASS_DEVICE_ATTR(ad_partner_mac, S_IRUGO, bonding_show_ad_partner_mac, NULL);
1306
1307
1308
1309static struct attribute *per_bond_attrs[] = {
1310 &class_device_attr_slaves.attr,
1311 &class_device_attr_mode.attr,
1312 &class_device_attr_arp_interval.attr,
1313 &class_device_attr_arp_ip_target.attr,
1314 &class_device_attr_downdelay.attr,
1315 &class_device_attr_updelay.attr,
1316 &class_device_attr_lacp_rate.attr,
1317 &class_device_attr_xmit_hash_policy.attr,
1318 &class_device_attr_miimon.attr,
1319 &class_device_attr_primary.attr,
1320 &class_device_attr_use_carrier.attr,
1321 &class_device_attr_active_slave.attr,
1322 &class_device_attr_mii_status.attr,
1323 &class_device_attr_ad_aggregator.attr,
1324 &class_device_attr_ad_num_ports.attr,
1325 &class_device_attr_ad_actor_key.attr,
1326 &class_device_attr_ad_partner_key.attr,
1327 &class_device_attr_ad_partner_mac.attr,
1328 NULL,
1329};
1330
1331static struct attribute_group bonding_group = {
1332 .name = "bonding",
1333 .attrs = per_bond_attrs,
1334};
1335
1336/*
1337 * Initialize sysfs. This sets up the bonding_masters file in
1338 * /sys/class/net.
1339 */
1340int bond_create_sysfs(void)
1341{
1342 int ret = 0;
1343 struct bonding *firstbond;
1344
1345 init_rwsem(&bonding_rwsem);
1346
1347 /* get the netdev class pointer */
1348 firstbond = container_of(bond_dev_list.next, struct bonding, bond_list);
1349 if (!firstbond)
1350 return -ENODEV;
1351
1352 netdev_class = firstbond->dev->class_dev.class;
1353 if (!netdev_class)
1354 return -ENODEV;
1355
1356 ret = class_create_file(netdev_class, &class_attr_bonding_masters);
1357
1358 return ret;
1359
1360}
1361
1362/*
1363 * Remove /sys/class/net/bonding_masters.
1364 */
1365void bond_destroy_sysfs(void)
1366{
1367 if (netdev_class)
1368 class_remove_file(netdev_class, &class_attr_bonding_masters);
1369}
1370
1371/*
1372 * Initialize sysfs for each bond. This sets up and registers
1373 * the 'bondctl' directory for each individual bond under /sys/class/net.
1374 */
1375int bond_create_sysfs_entry(struct bonding *bond)
1376{
1377 struct net_device *dev = bond->dev;
1378 int err;
1379
1380 err = sysfs_create_group(&(dev->class_dev.kobj), &bonding_group);
1381 if (err) {
1382 printk(KERN_EMERG "eek! didn't create group!\n");
1383 }
1384
1385 if (expected_refcount < 1)
1386 expected_refcount = atomic_read(&bond->dev->class_dev.kobj.kref.refcount);
1387
1388 return err;
1389}
1390/*
1391 * Remove sysfs entries for each bond.
1392 */
1393void bond_destroy_sysfs_entry(struct bonding *bond)
1394{
1395 struct net_device *dev = bond->dev;
1396
1397 sysfs_remove_group(&(dev->class_dev.kobj), &bonding_group);
1398}
1399
diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h
index 863605aab204..903e60aa611e 100644
--- a/drivers/net/bonding/bonding.h
+++ b/drivers/net/bonding/bonding.h
@@ -37,6 +37,7 @@
37#include <linux/timer.h> 37#include <linux/timer.h>
38#include <linux/proc_fs.h> 38#include <linux/proc_fs.h>
39#include <linux/if_bonding.h> 39#include <linux/if_bonding.h>
40#include <linux/kobject.h>
40#include "bond_3ad.h" 41#include "bond_3ad.h"
41#include "bond_alb.h" 42#include "bond_alb.h"
42 43
@@ -262,6 +263,12 @@ struct vlan_entry *bond_next_vlan(struct bonding *bond, struct vlan_entry *curr)
262int bond_dev_queue_xmit(struct bonding *bond, struct sk_buff *skb, struct net_device *slave_dev); 263int bond_dev_queue_xmit(struct bonding *bond, struct sk_buff *skb, struct net_device *slave_dev);
263int bond_create(char *name, struct bond_params *params, struct bonding **newbond); 264int bond_create(char *name, struct bond_params *params, struct bonding **newbond);
264void bond_deinit(struct net_device *bond_dev); 265void bond_deinit(struct net_device *bond_dev);
266int bond_create_sysfs(void);
267void bond_destroy_sysfs(void);
268void bond_destroy_sysfs_entry(struct bonding *bond);
269int bond_create_sysfs_entry(struct bonding *bond);
270int bond_create_slave_symlinks(struct net_device *master, struct net_device *slave);
271void bond_destroy_slave_symlinks(struct net_device *master, struct net_device *slave);
265int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev); 272int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev);
266int bond_release(struct net_device *bond_dev, struct net_device *slave_dev); 273int bond_release(struct net_device *bond_dev, struct net_device *slave_dev);
267int bond_sethwaddr(struct net_device *bond_dev, struct net_device *slave_dev); 274int bond_sethwaddr(struct net_device *bond_dev, struct net_device *slave_dev);