blob: 5f6babcfc26e6aa56881ef2dc24b1ed51e3d7539 [file] [log] [blame]
Mitch Williamsb76cdba2005-11-09 10:36:41 -08001/*
2 * Copyright(c) 2004-2005 Intel Corporation. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the
6 * Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
11 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * for more details.
13 *
14 * You should have received a copy of the GNU General Public License along
Jeff Kirsheradf8d3f2013-12-06 06:28:47 -080015 * with this program; if not, see <http://www.gnu.org/licenses/>.
Mitch Williamsb76cdba2005-11-09 10:36:41 -080016 *
17 * The full GNU General Public License is included in this distribution in the
18 * file called LICENSE.
19 *
Mitch Williamsb76cdba2005-11-09 10:36:41 -080020 */
Joe Perchesa4aee5c2009-12-13 20:06:07 -080021
22#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
23
Mitch Williamsb76cdba2005-11-09 10:36:41 -080024#include <linux/kernel.h>
25#include <linux/module.h>
Mitch Williamsb76cdba2005-11-09 10:36:41 -080026#include <linux/device.h>
Alexey Dobriyand43c36d2009-10-07 17:09:06 +040027#include <linux/sched.h>
Mitch Williamsb76cdba2005-11-09 10:36:41 -080028#include <linux/fs.h>
29#include <linux/types.h>
30#include <linux/string.h>
31#include <linux/netdevice.h>
32#include <linux/inetdevice.h>
33#include <linux/in.h>
34#include <linux/sysfs.h>
Mitch Williamsb76cdba2005-11-09 10:36:41 -080035#include <linux/ctype.h>
36#include <linux/inet.h>
37#include <linux/rtnetlink.h>
Stephen Hemminger5c5129b2009-06-12 19:02:51 +000038#include <linux/etherdevice.h>
Eric W. Biederman881d9662007-09-17 11:56:21 -070039#include <net/net_namespace.h>
Eric W. Biedermanec87fd32009-10-29 14:18:26 +000040#include <net/netns/generic.h>
41#include <linux/nsproxy.h>
Mitch Williamsb76cdba2005-11-09 10:36:41 -080042
Mitch Williamsb76cdba2005-11-09 10:36:41 -080043#include "bonding.h"
Holger Eitzenberger5a03cdb2008-12-09 23:09:22 -080044
Stephen Hemminger3d632c32009-06-12 19:02:48 +000045#define to_dev(obj) container_of(obj, struct device, kobj)
Wang Chen454d7c92008-11-12 23:37:49 -080046#define to_bond(cd) ((struct bonding *)(netdev_priv(to_net_dev(cd))))
Mitch Williamsb76cdba2005-11-09 10:36:41 -080047
Mitch Williamsb76cdba2005-11-09 10:36:41 -080048/*
49 * "show" function for the bond_masters attribute.
50 * The class parameter is ignored.
51 */
Andi Kleen28812fe2010-01-05 12:48:07 +010052static ssize_t bonding_show_bonds(struct class *cls,
53 struct class_attribute *attr,
54 char *buf)
Mitch Williamsb76cdba2005-11-09 10:36:41 -080055{
Eric W. Biederman4c224002011-10-12 21:56:25 +000056 struct bond_net *bn =
57 container_of(attr, struct bond_net, class_attr_bonding_masters);
Mitch Williamsb76cdba2005-11-09 10:36:41 -080058 int res = 0;
59 struct bonding *bond;
60
Stephen Hemminger7e083842009-06-12 19:02:46 +000061 rtnl_lock();
Mitch Williamsb76cdba2005-11-09 10:36:41 -080062
Eric W. Biedermanec87fd32009-10-29 14:18:26 +000063 list_for_each_entry(bond, &bn->dev_list, bond_list) {
Mitch Williamsb76cdba2005-11-09 10:36:41 -080064 if (res > (PAGE_SIZE - IFNAMSIZ)) {
65 /* not enough space for another interface name */
66 if ((PAGE_SIZE - res) > 10)
67 res = PAGE_SIZE - 10;
Wagner Ferencb8843662007-12-06 23:40:30 -080068 res += sprintf(buf + res, "++more++ ");
Mitch Williamsb76cdba2005-11-09 10:36:41 -080069 break;
70 }
Wagner Ferencb8843662007-12-06 23:40:30 -080071 res += sprintf(buf + res, "%s ", bond->dev->name);
Mitch Williamsb76cdba2005-11-09 10:36:41 -080072 }
Wagner Ferenc1dcdcd62007-12-06 23:40:31 -080073 if (res)
74 buf[res-1] = '\n'; /* eat the leftover space */
Stephen Hemminger7e083842009-06-12 19:02:46 +000075
76 rtnl_unlock();
Mitch Williamsb76cdba2005-11-09 10:36:41 -080077 return res;
78}
79
Eric W. Biederman4c224002011-10-12 21:56:25 +000080static struct net_device *bond_get_by_name(struct bond_net *bn, const char *ifname)
Stephen Hemminger373500d2009-06-12 19:02:50 +000081{
82 struct bonding *bond;
83
Eric W. Biedermanec87fd32009-10-29 14:18:26 +000084 list_for_each_entry(bond, &bn->dev_list, bond_list) {
Stephen Hemminger373500d2009-06-12 19:02:50 +000085 if (strncmp(bond->dev->name, ifname, IFNAMSIZ) == 0)
86 return bond->dev;
87 }
88 return NULL;
89}
90
Mitch Williamsb76cdba2005-11-09 10:36:41 -080091/*
92 * "store" function for the bond_masters attribute. This is what
93 * creates and deletes entire bonds.
94 *
95 * The class parameter is ignored.
96 *
97 */
98
Stephen Hemminger3d632c32009-06-12 19:02:48 +000099static ssize_t bonding_store_bonds(struct class *cls,
Andi Kleen28812fe2010-01-05 12:48:07 +0100100 struct class_attribute *attr,
Stephen Hemminger3d632c32009-06-12 19:02:48 +0000101 const char *buffer, size_t count)
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800102{
Eric W. Biederman4c224002011-10-12 21:56:25 +0000103 struct bond_net *bn =
104 container_of(attr, struct bond_net, class_attr_bonding_masters);
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800105 char command[IFNAMSIZ + 1] = {0, };
106 char *ifname;
Jay Vosburgh027ea042008-01-17 16:25:02 -0800107 int rv, res = count;
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800108
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800109 sscanf(buffer, "%16s", command); /* IFNAMSIZ*/
110 ifname = command + 1;
111 if ((strlen(command) <= 1) ||
112 !dev_valid_name(ifname))
113 goto err_no_cmd;
114
115 if (command[0] == '+') {
Joe Perchesa4aee5c2009-12-13 20:06:07 -0800116 pr_info("%s is being created...\n", ifname);
Eric W. Biederman4c224002011-10-12 21:56:25 +0000117 rv = bond_create(bn->net, ifname);
Jay Vosburgh027ea042008-01-17 16:25:02 -0800118 if (rv) {
Phil Oester5f86cad12011-03-14 06:22:06 +0000119 if (rv == -EEXIST)
Joe Perches90194262014-02-15 16:01:45 -0800120 pr_info("%s already exists\n", ifname);
Phil Oester5f86cad12011-03-14 06:22:06 +0000121 else
Joe Perches90194262014-02-15 16:01:45 -0800122 pr_info("%s creation failed\n", ifname);
Jay Vosburgh027ea042008-01-17 16:25:02 -0800123 res = rv;
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800124 }
Stephen Hemminger373500d2009-06-12 19:02:50 +0000125 } else if (command[0] == '-') {
126 struct net_device *bond_dev;
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800127
Jay Vosburgh027ea042008-01-17 16:25:02 -0800128 rtnl_lock();
Eric W. Biederman4c224002011-10-12 21:56:25 +0000129 bond_dev = bond_get_by_name(bn, ifname);
Stephen Hemminger373500d2009-06-12 19:02:50 +0000130 if (bond_dev) {
Joe Perchesa4aee5c2009-12-13 20:06:07 -0800131 pr_info("%s is being deleted...\n", ifname);
Stephen Hemminger373500d2009-06-12 19:02:50 +0000132 unregister_netdevice(bond_dev);
133 } else {
Joe Perchesa4aee5c2009-12-13 20:06:07 -0800134 pr_err("unable to delete non-existent %s\n", ifname);
Stephen Hemminger373500d2009-06-12 19:02:50 +0000135 res = -ENODEV;
136 }
137 rtnl_unlock();
138 } else
139 goto err_no_cmd;
Jay Vosburgh027ea042008-01-17 16:25:02 -0800140
Stephen Hemminger373500d2009-06-12 19:02:50 +0000141 /* Always return either count or an error. If you return 0, you'll
142 * get called forever, which is bad.
143 */
144 return res;
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800145
146err_no_cmd:
Joe Perches90194262014-02-15 16:01:45 -0800147 pr_err("no command found in bonding_masters - use +ifname or -ifname\n");
Jay Vosburghc4ebc662008-05-02 17:49:38 -0700148 return -EPERM;
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800149}
Stephen Hemminger373500d2009-06-12 19:02:50 +0000150
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800151/* class attribute for bond_masters file. This ends up in /sys/class/net */
Eric W. Biederman4c224002011-10-12 21:56:25 +0000152static const struct class_attribute class_attr_bonding_masters = {
153 .attr = {
154 .name = "bonding_masters",
155 .mode = S_IWUSR | S_IRUGO,
156 },
157 .show = bonding_show_bonds,
158 .store = bonding_store_bonds,
Eric W. Biederman4c224002011-10-12 21:56:25 +0000159};
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800160
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800161/*
162 * Show the slaves in the current bond.
163 */
Greg Kroah-Hartman43cb76d2002-04-09 12:14:34 -0700164static ssize_t bonding_show_slaves(struct device *d,
165 struct device_attribute *attr, char *buf)
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800166{
Greg Kroah-Hartman43cb76d2002-04-09 12:14:34 -0700167 struct bonding *bond = to_bond(d);
Veaceslav Falico9caff1e2013-09-25 09:20:14 +0200168 struct list_head *iter;
nikolay@redhat.comdec1e902013-08-01 16:54:47 +0200169 struct slave *slave;
170 int res = 0;
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800171
dingtianhong4d1ae5f2013-10-15 16:28:42 +0800172 if (!rtnl_trylock())
173 return restart_syscall();
174
Veaceslav Falico9caff1e2013-09-25 09:20:14 +0200175 bond_for_each_slave(bond, slave, iter) {
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800176 if (res > (PAGE_SIZE - IFNAMSIZ)) {
177 /* not enough space for another interface name */
178 if ((PAGE_SIZE - res) > 10)
179 res = PAGE_SIZE - 10;
Wagner Ferenc7bd46502007-12-06 23:40:28 -0800180 res += sprintf(buf + res, "++more++ ");
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800181 break;
182 }
183 res += sprintf(buf + res, "%s ", slave->dev->name);
184 }
dingtianhong4d1ae5f2013-10-15 16:28:42 +0800185
186 rtnl_unlock();
187
Wagner Ferenc1dcdcd62007-12-06 23:40:31 -0800188 if (res)
189 buf[res-1] = '\n'; /* eat the leftover space */
nikolay@redhat.comdec1e902013-08-01 16:54:47 +0200190
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800191 return res;
192}
193
194/*
Veaceslav Falicod6641cc2013-05-28 01:26:13 +0000195 * Set the slaves in the current bond.
Jiri Pirkof9f35452010-05-18 05:46:39 +0000196 * This is supposed to be only thin wrapper for bond_enslave and bond_release.
197 * All hard work should be done there.
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800198 */
Greg Kroah-Hartman43cb76d2002-04-09 12:14:34 -0700199static ssize_t bonding_store_slaves(struct device *d,
200 struct device_attribute *attr,
201 const char *buffer, size_t count)
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800202{
Greg Kroah-Hartman43cb76d2002-04-09 12:14:34 -0700203 struct bonding *bond = to_bond(d);
Nikolay Aleksandrov0e2e5b62014-01-22 14:53:40 +0100204 int ret;
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800205
Nikolay Aleksandrov0e2e5b62014-01-22 14:53:40 +0100206 ret = bond_opt_tryset_rtnl(bond, BOND_OPT_SLAVES, (char *)buffer);
207 if (!ret)
208 ret = count;
Jay Vosburgh027ea042008-01-17 16:25:02 -0800209
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800210 return ret;
211}
Stephen Hemminger3d632c32009-06-12 19:02:48 +0000212static DEVICE_ATTR(slaves, S_IRUGO | S_IWUSR, bonding_show_slaves,
213 bonding_store_slaves);
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800214
215/*
216 * Show and set the bonding mode. The bond interface must be down to
217 * change the mode.
218 */
Greg Kroah-Hartman43cb76d2002-04-09 12:14:34 -0700219static ssize_t bonding_show_mode(struct device *d,
220 struct device_attribute *attr, char *buf)
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800221{
Greg Kroah-Hartman43cb76d2002-04-09 12:14:34 -0700222 struct bonding *bond = to_bond(d);
stephen hemmingerf3253332014-03-04 16:36:44 -0800223 const struct bond_opt_value *val;
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800224
Nikolay Aleksandrov2b3798d2014-01-22 14:53:17 +0100225 val = bond_opt_get_val(BOND_OPT_MODE, bond->params.mode);
226
227 return sprintf(buf, "%s %d\n", val->string, bond->params.mode);
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800228}
229
Greg Kroah-Hartman43cb76d2002-04-09 12:14:34 -0700230static ssize_t bonding_store_mode(struct device *d,
231 struct device_attribute *attr,
232 const char *buf, size_t count)
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800233{
Greg Kroah-Hartman43cb76d2002-04-09 12:14:34 -0700234 struct bonding *bond = to_bond(d);
Nikolay Aleksandrov2b3798d2014-01-22 14:53:17 +0100235 int ret;
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800236
Nikolay Aleksandrov2b3798d2014-01-22 14:53:17 +0100237 ret = bond_opt_tryset_rtnl(bond, BOND_OPT_MODE, (char *)buf);
238 if (!ret)
Jiri Pirko72be35f2013-10-18 17:43:34 +0200239 ret = count;
Andy Gospodarekc5cb0022010-07-28 15:13:56 +0000240
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800241 return ret;
242}
Stephen Hemminger3d632c32009-06-12 19:02:48 +0000243static DEVICE_ATTR(mode, S_IRUGO | S_IWUSR,
244 bonding_show_mode, bonding_store_mode);
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800245
246/*
Stephen Hemminger3d632c32009-06-12 19:02:48 +0000247 * Show and set the bonding transmit hash method.
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800248 */
Greg Kroah-Hartman43cb76d2002-04-09 12:14:34 -0700249static ssize_t bonding_show_xmit_hash(struct device *d,
250 struct device_attribute *attr,
251 char *buf)
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800252{
Greg Kroah-Hartman43cb76d2002-04-09 12:14:34 -0700253 struct bonding *bond = to_bond(d);
stephen hemmingerf3253332014-03-04 16:36:44 -0800254 const struct bond_opt_value *val;
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800255
Nikolay Aleksandrova4b32ce2014-01-22 14:53:19 +0100256 val = bond_opt_get_val(BOND_OPT_XMIT_HASH, bond->params.xmit_policy);
257
258 return sprintf(buf, "%s %d\n", val->string, bond->params.xmit_policy);
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800259}
260
Greg Kroah-Hartman43cb76d2002-04-09 12:14:34 -0700261static ssize_t bonding_store_xmit_hash(struct device *d,
262 struct device_attribute *attr,
263 const char *buf, size_t count)
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800264{
Greg Kroah-Hartman43cb76d2002-04-09 12:14:34 -0700265 struct bonding *bond = to_bond(d);
Nikolay Aleksandrova4b32ce2014-01-22 14:53:19 +0100266 int ret;
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800267
Nikolay Aleksandrova4b32ce2014-01-22 14:53:19 +0100268 ret = bond_opt_tryset_rtnl(bond, BOND_OPT_XMIT_HASH, (char *)buf);
sfeldma@cumulusnetworks.comf70161c2013-12-15 16:42:12 -0800269 if (!ret)
270 ret = count;
271
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800272 return ret;
273}
Stephen Hemminger3d632c32009-06-12 19:02:48 +0000274static DEVICE_ATTR(xmit_hash_policy, S_IRUGO | S_IWUSR,
275 bonding_show_xmit_hash, bonding_store_xmit_hash);
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800276
277/*
Jay Vosburghf5b2b962006-09-22 21:54:53 -0700278 * Show and set arp_validate.
279 */
Greg Kroah-Hartman43cb76d2002-04-09 12:14:34 -0700280static ssize_t bonding_show_arp_validate(struct device *d,
281 struct device_attribute *attr,
282 char *buf)
Jay Vosburghf5b2b962006-09-22 21:54:53 -0700283{
Greg Kroah-Hartman43cb76d2002-04-09 12:14:34 -0700284 struct bonding *bond = to_bond(d);
stephen hemmingerf3253332014-03-04 16:36:44 -0800285 const struct bond_opt_value *val;
Jay Vosburghf5b2b962006-09-22 21:54:53 -0700286
Nikolay Aleksandrov16228882014-01-22 14:53:20 +0100287 val = bond_opt_get_val(BOND_OPT_ARP_VALIDATE,
288 bond->params.arp_validate);
289
290 return sprintf(buf, "%s %d\n", val->string, bond->params.arp_validate);
Jay Vosburghf5b2b962006-09-22 21:54:53 -0700291}
292
Greg Kroah-Hartman43cb76d2002-04-09 12:14:34 -0700293static ssize_t bonding_store_arp_validate(struct device *d,
294 struct device_attribute *attr,
295 const char *buf, size_t count)
Jay Vosburghf5b2b962006-09-22 21:54:53 -0700296{
Greg Kroah-Hartman43cb76d2002-04-09 12:14:34 -0700297 struct bonding *bond = to_bond(d);
Nikolay Aleksandrov16228882014-01-22 14:53:20 +0100298 int ret;
Jay Vosburghf5b2b962006-09-22 21:54:53 -0700299
Nikolay Aleksandrov16228882014-01-22 14:53:20 +0100300 ret = bond_opt_tryset_rtnl(bond, BOND_OPT_ARP_VALIDATE, (char *)buf);
sfeldma@cumulusnetworks.com29c49482013-12-12 14:10:38 -0800301 if (!ret)
302 ret = count;
303
nikolay@redhat.com5c5038d2013-09-07 00:00:25 +0200304 return ret;
Jay Vosburghf5b2b962006-09-22 21:54:53 -0700305}
306
Stephen Hemminger3d632c32009-06-12 19:02:48 +0000307static DEVICE_ATTR(arp_validate, S_IRUGO | S_IWUSR, bonding_show_arp_validate,
308 bonding_store_arp_validate);
Veaceslav Falico8599b522013-06-24 11:49:34 +0200309/*
310 * Show and set arp_all_targets.
311 */
312static ssize_t bonding_show_arp_all_targets(struct device *d,
313 struct device_attribute *attr,
314 char *buf)
315{
316 struct bonding *bond = to_bond(d);
stephen hemmingerf3253332014-03-04 16:36:44 -0800317 const struct bond_opt_value *val;
Veaceslav Falico8599b522013-06-24 11:49:34 +0200318
Nikolay Aleksandrovedf36b22014-01-22 14:53:21 +0100319 val = bond_opt_get_val(BOND_OPT_ARP_ALL_TARGETS,
320 bond->params.arp_all_targets);
321 return sprintf(buf, "%s %d\n",
322 val->string, bond->params.arp_all_targets);
Veaceslav Falico8599b522013-06-24 11:49:34 +0200323}
324
325static ssize_t bonding_store_arp_all_targets(struct device *d,
326 struct device_attribute *attr,
327 const char *buf, size_t count)
328{
329 struct bonding *bond = to_bond(d);
Nikolay Aleksandrovedf36b22014-01-22 14:53:21 +0100330 int ret;
Veaceslav Falico8599b522013-06-24 11:49:34 +0200331
Nikolay Aleksandrovedf36b22014-01-22 14:53:21 +0100332 ret = bond_opt_tryset_rtnl(bond, BOND_OPT_ARP_ALL_TARGETS, (char *)buf);
sfeldma@cumulusnetworks.comd5c84252013-12-12 14:10:45 -0800333 if (!ret)
334 ret = count;
335
sfeldma@cumulusnetworks.comd5c84252013-12-12 14:10:45 -0800336 return ret;
Veaceslav Falico8599b522013-06-24 11:49:34 +0200337}
338
339static DEVICE_ATTR(arp_all_targets, S_IRUGO | S_IWUSR,
340 bonding_show_arp_all_targets, bonding_store_arp_all_targets);
Jay Vosburghf5b2b962006-09-22 21:54:53 -0700341
342/*
Jay Vosburghdd957c52007-10-09 19:57:24 -0700343 * Show and store fail_over_mac. User only allowed to change the
344 * value when there are no slaves.
345 */
Stephen Hemminger3d632c32009-06-12 19:02:48 +0000346static ssize_t bonding_show_fail_over_mac(struct device *d,
347 struct device_attribute *attr,
348 char *buf)
Jay Vosburghdd957c52007-10-09 19:57:24 -0700349{
350 struct bonding *bond = to_bond(d);
stephen hemmingerf3253332014-03-04 16:36:44 -0800351 const struct bond_opt_value *val;
Jay Vosburghdd957c52007-10-09 19:57:24 -0700352
Nikolay Aleksandrov1df6b6a2014-01-22 14:53:22 +0100353 val = bond_opt_get_val(BOND_OPT_FAIL_OVER_MAC,
354 bond->params.fail_over_mac);
355
356 return sprintf(buf, "%s %d\n", val->string, bond->params.fail_over_mac);
Jay Vosburghdd957c52007-10-09 19:57:24 -0700357}
358
Stephen Hemminger3d632c32009-06-12 19:02:48 +0000359static ssize_t bonding_store_fail_over_mac(struct device *d,
360 struct device_attribute *attr,
361 const char *buf, size_t count)
Jay Vosburghdd957c52007-10-09 19:57:24 -0700362{
Jay Vosburghdd957c52007-10-09 19:57:24 -0700363 struct bonding *bond = to_bond(d);
Nikolay Aleksandrov1df6b6a2014-01-22 14:53:22 +0100364 int ret;
Jay Vosburghdd957c52007-10-09 19:57:24 -0700365
Nikolay Aleksandrov1df6b6a2014-01-22 14:53:22 +0100366 ret = bond_opt_tryset_rtnl(bond, BOND_OPT_FAIL_OVER_MAC, (char *)buf);
sfeldma@cumulusnetworks.com89901972013-12-15 16:42:05 -0800367 if (!ret)
368 ret = count;
369
dingtianhong9402b742013-07-23 15:25:39 +0800370 return ret;
Jay Vosburghdd957c52007-10-09 19:57:24 -0700371}
372
Stephen Hemminger3d632c32009-06-12 19:02:48 +0000373static DEVICE_ATTR(fail_over_mac, S_IRUGO | S_IWUSR,
374 bonding_show_fail_over_mac, bonding_store_fail_over_mac);
Jay Vosburghdd957c52007-10-09 19:57:24 -0700375
376/*
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800377 * Show and set the arp timer interval. There are two tricky bits
378 * here. First, if ARP monitoring is activated, then we must disable
379 * MII monitoring. Second, if the ARP timer isn't running, we must
380 * start it.
381 */
Greg Kroah-Hartman43cb76d2002-04-09 12:14:34 -0700382static ssize_t bonding_show_arp_interval(struct device *d,
383 struct device_attribute *attr,
384 char *buf)
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800385{
Greg Kroah-Hartman43cb76d2002-04-09 12:14:34 -0700386 struct bonding *bond = to_bond(d);
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800387
Wagner Ferenc7bd46502007-12-06 23:40:28 -0800388 return sprintf(buf, "%d\n", bond->params.arp_interval);
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800389}
390
Greg Kroah-Hartman43cb76d2002-04-09 12:14:34 -0700391static ssize_t bonding_store_arp_interval(struct device *d,
392 struct device_attribute *attr,
393 const char *buf, size_t count)
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800394{
Greg Kroah-Hartman43cb76d2002-04-09 12:14:34 -0700395 struct bonding *bond = to_bond(d);
Nikolay Aleksandrov7bdb04e2014-01-22 14:53:23 +0100396 int ret;
sfeldma@cumulusnetworks.com06151db2013-12-12 14:10:24 -0800397
Nikolay Aleksandrov7bdb04e2014-01-22 14:53:23 +0100398 ret = bond_opt_tryset_rtnl(bond, BOND_OPT_ARP_INTERVAL, (char *)buf);
sfeldma@cumulusnetworks.com06151db2013-12-12 14:10:24 -0800399 if (!ret)
400 ret = count;
401
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800402 return ret;
403}
Stephen Hemminger3d632c32009-06-12 19:02:48 +0000404static DEVICE_ATTR(arp_interval, S_IRUGO | S_IWUSR,
405 bonding_show_arp_interval, bonding_store_arp_interval);
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800406
407/*
408 * Show and set the arp targets.
409 */
Greg Kroah-Hartman43cb76d2002-04-09 12:14:34 -0700410static ssize_t bonding_show_arp_targets(struct device *d,
411 struct device_attribute *attr,
412 char *buf)
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800413{
Greg Kroah-Hartman43cb76d2002-04-09 12:14:34 -0700414 struct bonding *bond = to_bond(d);
Nikolay Aleksandrov4fb0ef52014-01-22 14:53:24 +0100415 int i, res = 0;
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800416
417 for (i = 0; i < BOND_MAX_ARP_TARGETS; i++) {
418 if (bond->params.arp_targets[i])
Harvey Harrison63779432008-10-31 00:56:00 -0700419 res += sprintf(buf + res, "%pI4 ",
420 &bond->params.arp_targets[i]);
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800421 }
Wagner Ferenc1dcdcd62007-12-06 23:40:31 -0800422 if (res)
423 buf[res-1] = '\n'; /* eat the leftover space */
Nikolay Aleksandrov4fb0ef52014-01-22 14:53:24 +0100424
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800425 return res;
426}
427
Greg Kroah-Hartman43cb76d2002-04-09 12:14:34 -0700428static ssize_t bonding_store_arp_targets(struct device *d,
429 struct device_attribute *attr,
430 const char *buf, size_t count)
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800431{
Greg Kroah-Hartman43cb76d2002-04-09 12:14:34 -0700432 struct bonding *bond = to_bond(d);
Nikolay Aleksandrov4fb0ef52014-01-22 14:53:24 +0100433 int ret;
sfeldma@cumulusnetworks.com7f28fa12013-12-12 14:10:31 -0800434
Nikolay Aleksandrov4fb0ef52014-01-22 14:53:24 +0100435 ret = bond_opt_tryset_rtnl(bond, BOND_OPT_ARP_TARGETS, (char *)buf);
sfeldma@cumulusnetworks.com7f28fa12013-12-12 14:10:31 -0800436 if (!ret)
437 ret = count;
438
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800439 return ret;
440}
Greg Kroah-Hartman43cb76d2002-04-09 12:14:34 -0700441static DEVICE_ATTR(arp_ip_target, S_IRUGO | S_IWUSR , bonding_show_arp_targets, bonding_store_arp_targets);
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800442
443/*
444 * Show and set the up and down delays. These must be multiples of the
445 * MII monitoring value, and are stored internally as the multiplier.
446 * Thus, we must translate to MS for the real world.
447 */
Greg Kroah-Hartman43cb76d2002-04-09 12:14:34 -0700448static ssize_t bonding_show_downdelay(struct device *d,
449 struct device_attribute *attr,
450 char *buf)
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800451{
Greg Kroah-Hartman43cb76d2002-04-09 12:14:34 -0700452 struct bonding *bond = to_bond(d);
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800453
Wagner Ferenc7bd46502007-12-06 23:40:28 -0800454 return sprintf(buf, "%d\n", bond->params.downdelay * bond->params.miimon);
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800455}
456
Greg Kroah-Hartman43cb76d2002-04-09 12:14:34 -0700457static ssize_t bonding_store_downdelay(struct device *d,
458 struct device_attribute *attr,
459 const char *buf, size_t count)
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800460{
Greg Kroah-Hartman43cb76d2002-04-09 12:14:34 -0700461 struct bonding *bond = to_bond(d);
Nikolay Aleksandrov25a9b542014-01-22 14:53:25 +0100462 int ret;
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800463
Nikolay Aleksandrov25a9b542014-01-22 14:53:25 +0100464 ret = bond_opt_tryset_rtnl(bond, BOND_OPT_DOWNDELAY, (char *)buf);
sfeldma@cumulusnetworks.comc7461f92013-12-12 14:10:09 -0800465 if (!ret)
466 ret = count;
467
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800468 return ret;
469}
Stephen Hemminger3d632c32009-06-12 19:02:48 +0000470static DEVICE_ATTR(downdelay, S_IRUGO | S_IWUSR,
471 bonding_show_downdelay, bonding_store_downdelay);
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800472
Greg Kroah-Hartman43cb76d2002-04-09 12:14:34 -0700473static ssize_t bonding_show_updelay(struct device *d,
474 struct device_attribute *attr,
475 char *buf)
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800476{
Greg Kroah-Hartman43cb76d2002-04-09 12:14:34 -0700477 struct bonding *bond = to_bond(d);
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800478
Wagner Ferenc7bd46502007-12-06 23:40:28 -0800479 return sprintf(buf, "%d\n", bond->params.updelay * bond->params.miimon);
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800480
481}
482
Greg Kroah-Hartman43cb76d2002-04-09 12:14:34 -0700483static ssize_t bonding_store_updelay(struct device *d,
484 struct device_attribute *attr,
485 const char *buf, size_t count)
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800486{
Greg Kroah-Hartman43cb76d2002-04-09 12:14:34 -0700487 struct bonding *bond = to_bond(d);
Nikolay Aleksandrove4994612014-01-22 14:53:26 +0100488 int ret;
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800489
Nikolay Aleksandrove4994612014-01-22 14:53:26 +0100490 ret = bond_opt_tryset_rtnl(bond, BOND_OPT_UPDELAY, (char *)buf);
sfeldma@cumulusnetworks.com25852e22013-12-12 14:10:02 -0800491 if (!ret)
492 ret = count;
493
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800494 return ret;
495}
Stephen Hemminger3d632c32009-06-12 19:02:48 +0000496static DEVICE_ATTR(updelay, S_IRUGO | S_IWUSR,
497 bonding_show_updelay, bonding_store_updelay);
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800498
499/*
500 * Show and set the LACP interval. Interface must be down, and the mode
501 * must be set to 802.3ad mode.
502 */
Greg Kroah-Hartman43cb76d2002-04-09 12:14:34 -0700503static ssize_t bonding_show_lacp(struct device *d,
504 struct device_attribute *attr,
505 char *buf)
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800506{
Greg Kroah-Hartman43cb76d2002-04-09 12:14:34 -0700507 struct bonding *bond = to_bond(d);
stephen hemmingerf3253332014-03-04 16:36:44 -0800508 const struct bond_opt_value *val;
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800509
Nikolay Aleksandrovd3131de2014-01-22 14:53:27 +0100510 val = bond_opt_get_val(BOND_OPT_LACP_RATE, bond->params.lacp_fast);
511
512 return sprintf(buf, "%s %d\n", val->string, bond->params.lacp_fast);
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800513}
514
Greg Kroah-Hartman43cb76d2002-04-09 12:14:34 -0700515static ssize_t bonding_store_lacp(struct device *d,
516 struct device_attribute *attr,
517 const char *buf, size_t count)
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800518{
Greg Kroah-Hartman43cb76d2002-04-09 12:14:34 -0700519 struct bonding *bond = to_bond(d);
Nikolay Aleksandrovd3131de2014-01-22 14:53:27 +0100520 int ret;
sfeldma@cumulusnetworks.com998e40bb2014-01-03 14:18:41 -0800521
Nikolay Aleksandrovd3131de2014-01-22 14:53:27 +0100522 ret = bond_opt_tryset_rtnl(bond, BOND_OPT_LACP_RATE, (char *)buf);
sfeldma@cumulusnetworks.com998e40bb2014-01-03 14:18:41 -0800523 if (!ret)
524 ret = count;
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800525
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800526 return ret;
527}
Stephen Hemminger3d632c32009-06-12 19:02:48 +0000528static DEVICE_ATTR(lacp_rate, S_IRUGO | S_IWUSR,
529 bonding_show_lacp, bonding_store_lacp);
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800530
stephen hemminger655f8912011-06-22 09:54:39 +0000531static ssize_t bonding_show_min_links(struct device *d,
532 struct device_attribute *attr,
533 char *buf)
534{
535 struct bonding *bond = to_bond(d);
536
Masanari Iida014f1b22014-04-29 00:41:21 +0900537 return sprintf(buf, "%u\n", bond->params.min_links);
stephen hemminger655f8912011-06-22 09:54:39 +0000538}
539
540static ssize_t bonding_store_min_links(struct device *d,
541 struct device_attribute *attr,
542 const char *buf, size_t count)
543{
544 struct bonding *bond = to_bond(d);
545 int ret;
stephen hemminger655f8912011-06-22 09:54:39 +0000546
Nikolay Aleksandrov633ddc92014-01-22 14:53:28 +0100547 ret = bond_opt_tryset_rtnl(bond, BOND_OPT_MINLINKS, (char *)buf);
sfeldma@cumulusnetworks.com7d101002013-12-17 21:30:23 -0800548 if (!ret)
549 ret = count;
550
sfeldma@cumulusnetworks.com7d101002013-12-17 21:30:23 -0800551 return ret;
stephen hemminger655f8912011-06-22 09:54:39 +0000552}
553static DEVICE_ATTR(min_links, S_IRUGO | S_IWUSR,
554 bonding_show_min_links, bonding_store_min_links);
555
Jay Vosburghfd989c82008-11-04 17:51:16 -0800556static ssize_t bonding_show_ad_select(struct device *d,
557 struct device_attribute *attr,
558 char *buf)
559{
560 struct bonding *bond = to_bond(d);
stephen hemmingerf3253332014-03-04 16:36:44 -0800561 const struct bond_opt_value *val;
Jay Vosburghfd989c82008-11-04 17:51:16 -0800562
Nikolay Aleksandrov9e5f5ee2014-01-22 14:53:29 +0100563 val = bond_opt_get_val(BOND_OPT_AD_SELECT, bond->params.ad_select);
564
565 return sprintf(buf, "%s %d\n", val->string, bond->params.ad_select);
Jay Vosburghfd989c82008-11-04 17:51:16 -0800566}
567
568
569static ssize_t bonding_store_ad_select(struct device *d,
570 struct device_attribute *attr,
571 const char *buf, size_t count)
572{
Jay Vosburghfd989c82008-11-04 17:51:16 -0800573 struct bonding *bond = to_bond(d);
Nikolay Aleksandrov9e5f5ee2014-01-22 14:53:29 +0100574 int ret;
Jay Vosburghfd989c82008-11-04 17:51:16 -0800575
Nikolay Aleksandrov9e5f5ee2014-01-22 14:53:29 +0100576 ret = bond_opt_tryset_rtnl(bond, BOND_OPT_AD_SELECT, (char *)buf);
sfeldma@cumulusnetworks.comec029fa2014-01-03 14:18:49 -0800577 if (!ret)
578 ret = count;
579
Jay Vosburghfd989c82008-11-04 17:51:16 -0800580 return ret;
581}
Stephen Hemminger3d632c32009-06-12 19:02:48 +0000582static DEVICE_ATTR(ad_select, S_IRUGO | S_IWUSR,
583 bonding_show_ad_select, bonding_store_ad_select);
Jay Vosburghfd989c82008-11-04 17:51:16 -0800584
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800585/*
Ben Hutchingsad246c92011-04-26 15:25:52 +0000586 * Show and set the number of peer notifications to send after a failover event.
587 */
588static ssize_t bonding_show_num_peer_notif(struct device *d,
589 struct device_attribute *attr,
590 char *buf)
591{
592 struct bonding *bond = to_bond(d);
593 return sprintf(buf, "%d\n", bond->params.num_peer_notif);
594}
595
596static ssize_t bonding_store_num_peer_notif(struct device *d,
597 struct device_attribute *attr,
598 const char *buf, size_t count)
599{
600 struct bonding *bond = to_bond(d);
sfeldma@cumulusnetworks.com2c9839c2013-12-17 21:30:09 -0800601 int ret;
602
Nikolay Aleksandrovef56bec2014-01-22 14:53:30 +0100603 ret = bond_opt_tryset_rtnl(bond, BOND_OPT_NUM_PEER_NOTIF, (char *)buf);
sfeldma@cumulusnetworks.com2c9839c2013-12-17 21:30:09 -0800604 if (!ret)
605 ret = count;
606
sfeldma@cumulusnetworks.com2c9839c2013-12-17 21:30:09 -0800607 return ret;
Ben Hutchingsad246c92011-04-26 15:25:52 +0000608}
609static DEVICE_ATTR(num_grat_arp, S_IRUGO | S_IWUSR,
610 bonding_show_num_peer_notif, bonding_store_num_peer_notif);
611static DEVICE_ATTR(num_unsol_na, S_IRUGO | S_IWUSR,
612 bonding_show_num_peer_notif, bonding_store_num_peer_notif);
613
614/*
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800615 * Show and set the MII monitor interval. There are two tricky bits
616 * here. First, if MII monitoring is activated, then we must disable
617 * ARP monitoring. Second, if the timer isn't running, we must
618 * start it.
619 */
Greg Kroah-Hartman43cb76d2002-04-09 12:14:34 -0700620static ssize_t bonding_show_miimon(struct device *d,
621 struct device_attribute *attr,
622 char *buf)
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800623{
Greg Kroah-Hartman43cb76d2002-04-09 12:14:34 -0700624 struct bonding *bond = to_bond(d);
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800625
Wagner Ferenc7bd46502007-12-06 23:40:28 -0800626 return sprintf(buf, "%d\n", bond->params.miimon);
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800627}
628
Greg Kroah-Hartman43cb76d2002-04-09 12:14:34 -0700629static ssize_t bonding_store_miimon(struct device *d,
630 struct device_attribute *attr,
631 const char *buf, size_t count)
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800632{
Greg Kroah-Hartman43cb76d2002-04-09 12:14:34 -0700633 struct bonding *bond = to_bond(d);
Nikolay Aleksandrovb98d9c62014-01-22 14:53:31 +0100634 int ret;
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800635
Nikolay Aleksandrovb98d9c62014-01-22 14:53:31 +0100636 ret = bond_opt_tryset_rtnl(bond, BOND_OPT_MIIMON, (char *)buf);
sfeldma@cumulusnetworks.comeecdaa62013-12-12 14:09:55 -0800637 if (!ret)
638 ret = count;
639
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800640 return ret;
641}
Stephen Hemminger3d632c32009-06-12 19:02:48 +0000642static DEVICE_ATTR(miimon, S_IRUGO | S_IWUSR,
643 bonding_show_miimon, bonding_store_miimon);
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800644
645/*
646 * Show and set the primary slave. The store function is much
647 * simpler than bonding_store_slaves function because it only needs to
648 * handle one interface name.
649 * The bond must be a mode that supports a primary for this be
650 * set.
651 */
Greg Kroah-Hartman43cb76d2002-04-09 12:14:34 -0700652static ssize_t bonding_show_primary(struct device *d,
653 struct device_attribute *attr,
654 char *buf)
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800655{
656 int count = 0;
Greg Kroah-Hartman43cb76d2002-04-09 12:14:34 -0700657 struct bonding *bond = to_bond(d);
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800658
659 if (bond->primary_slave)
Wagner Ferenc7bd46502007-12-06 23:40:28 -0800660 count = sprintf(buf, "%s\n", bond->primary_slave->dev->name);
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800661
662 return count;
663}
664
Greg Kroah-Hartman43cb76d2002-04-09 12:14:34 -0700665static ssize_t bonding_store_primary(struct device *d,
666 struct device_attribute *attr,
667 const char *buf, size_t count)
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800668{
Greg Kroah-Hartman43cb76d2002-04-09 12:14:34 -0700669 struct bonding *bond = to_bond(d);
sfeldma@cumulusnetworks.com0a98a0d2013-12-15 16:41:51 -0800670 int ret;
671
Nikolay Aleksandrov180222f2014-01-22 14:53:32 +0100672 ret = bond_opt_tryset_rtnl(bond, BOND_OPT_PRIMARY, (char *)buf);
sfeldma@cumulusnetworks.com0a98a0d2013-12-15 16:41:51 -0800673 if (!ret)
674 ret = count;
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800675
sfeldma@cumulusnetworks.com0a98a0d2013-12-15 16:41:51 -0800676 return ret;
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800677}
Stephen Hemminger3d632c32009-06-12 19:02:48 +0000678static DEVICE_ATTR(primary, S_IRUGO | S_IWUSR,
679 bonding_show_primary, bonding_store_primary);
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800680
681/*
Jiri Pirkoa5499522009-09-25 03:28:09 +0000682 * Show and set the primary_reselect flag.
683 */
684static ssize_t bonding_show_primary_reselect(struct device *d,
685 struct device_attribute *attr,
686 char *buf)
687{
688 struct bonding *bond = to_bond(d);
stephen hemmingerf3253332014-03-04 16:36:44 -0800689 const struct bond_opt_value *val;
Nikolay Aleksandrov388d3a62014-01-22 14:53:33 +0100690
691 val = bond_opt_get_val(BOND_OPT_PRIMARY_RESELECT,
692 bond->params.primary_reselect);
Jiri Pirkoa5499522009-09-25 03:28:09 +0000693
694 return sprintf(buf, "%s %d\n",
Nikolay Aleksandrov388d3a62014-01-22 14:53:33 +0100695 val->string, bond->params.primary_reselect);
Jiri Pirkoa5499522009-09-25 03:28:09 +0000696}
697
698static ssize_t bonding_store_primary_reselect(struct device *d,
699 struct device_attribute *attr,
700 const char *buf, size_t count)
701{
Jiri Pirkoa5499522009-09-25 03:28:09 +0000702 struct bonding *bond = to_bond(d);
Nikolay Aleksandrov388d3a62014-01-22 14:53:33 +0100703 int ret;
Jiri Pirkoa5499522009-09-25 03:28:09 +0000704
Nikolay Aleksandrov388d3a62014-01-22 14:53:33 +0100705 ret = bond_opt_tryset_rtnl(bond, BOND_OPT_PRIMARY_RESELECT,
706 (char *)buf);
sfeldma@cumulusnetworks.com8a41ae42013-12-15 16:41:58 -0800707 if (!ret)
708 ret = count;
709
Jiri Pirkoa5499522009-09-25 03:28:09 +0000710 return ret;
711}
712static DEVICE_ATTR(primary_reselect, S_IRUGO | S_IWUSR,
713 bonding_show_primary_reselect,
714 bonding_store_primary_reselect);
715
716/*
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800717 * Show and set the use_carrier flag.
718 */
Greg Kroah-Hartman43cb76d2002-04-09 12:14:34 -0700719static ssize_t bonding_show_carrier(struct device *d,
720 struct device_attribute *attr,
721 char *buf)
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800722{
Greg Kroah-Hartman43cb76d2002-04-09 12:14:34 -0700723 struct bonding *bond = to_bond(d);
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800724
Wagner Ferenc7bd46502007-12-06 23:40:28 -0800725 return sprintf(buf, "%d\n", bond->params.use_carrier);
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800726}
727
Greg Kroah-Hartman43cb76d2002-04-09 12:14:34 -0700728static ssize_t bonding_store_carrier(struct device *d,
729 struct device_attribute *attr,
730 const char *buf, size_t count)
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800731{
Greg Kroah-Hartman43cb76d2002-04-09 12:14:34 -0700732 struct bonding *bond = to_bond(d);
Nikolay Aleksandrov0fff0602014-01-22 14:53:34 +0100733 int ret;
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800734
Nikolay Aleksandrov0fff0602014-01-22 14:53:34 +0100735 ret = bond_opt_tryset_rtnl(bond, BOND_OPT_USE_CARRIER, (char *)buf);
sfeldma@cumulusnetworks.com9f53e142013-12-12 14:10:16 -0800736 if (!ret)
737 ret = count;
738
Jiri Pirko672bda32011-01-25 11:03:25 +0000739 return ret;
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800740}
Stephen Hemminger3d632c32009-06-12 19:02:48 +0000741static DEVICE_ATTR(use_carrier, S_IRUGO | S_IWUSR,
742 bonding_show_carrier, bonding_store_carrier);
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800743
744
745/*
746 * Show and set currently active_slave.
747 */
Greg Kroah-Hartman43cb76d2002-04-09 12:14:34 -0700748static ssize_t bonding_show_active_slave(struct device *d,
749 struct device_attribute *attr,
750 char *buf)
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800751{
Greg Kroah-Hartman43cb76d2002-04-09 12:14:34 -0700752 struct bonding *bond = to_bond(d);
Jiri Pirko752d48b2013-10-18 17:43:37 +0200753 struct net_device *slave_dev;
Wagner Ferenc16cd0162007-12-06 23:40:29 -0800754 int count = 0;
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800755
nikolay@redhat.com278b2082013-08-01 16:54:51 +0200756 rcu_read_lock();
Jiri Pirko752d48b2013-10-18 17:43:37 +0200757 slave_dev = bond_option_active_slave_get_rcu(bond);
758 if (slave_dev)
759 count = sprintf(buf, "%s\n", slave_dev->name);
nikolay@redhat.com278b2082013-08-01 16:54:51 +0200760 rcu_read_unlock();
761
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800762 return count;
763}
764
Greg Kroah-Hartman43cb76d2002-04-09 12:14:34 -0700765static ssize_t bonding_store_active_slave(struct device *d,
766 struct device_attribute *attr,
767 const char *buf, size_t count)
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800768{
Greg Kroah-Hartman43cb76d2002-04-09 12:14:34 -0700769 struct bonding *bond = to_bond(d);
Nikolay Aleksandrovd1fbd3e2014-01-22 14:53:35 +0100770 int ret;
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800771
Nikolay Aleksandrovd1fbd3e2014-01-22 14:53:35 +0100772 ret = bond_opt_tryset_rtnl(bond, BOND_OPT_ACTIVE_SLAVE, (char *)buf);
Jiri Pirkod9e32b22013-10-18 17:43:35 +0200773 if (!ret)
774 ret = count;
Neil Hormane843fa52010-10-13 16:01:50 +0000775
Jiri Pirkod9e32b22013-10-18 17:43:35 +0200776 return ret;
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800777}
Stephen Hemminger3d632c32009-06-12 19:02:48 +0000778static DEVICE_ATTR(active_slave, S_IRUGO | S_IWUSR,
779 bonding_show_active_slave, bonding_store_active_slave);
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800780
781
782/*
783 * Show link status of the bond interface.
784 */
Greg Kroah-Hartman43cb76d2002-04-09 12:14:34 -0700785static ssize_t bonding_show_mii_status(struct device *d,
786 struct device_attribute *attr,
787 char *buf)
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800788{
Greg Kroah-Hartman43cb76d2002-04-09 12:14:34 -0700789 struct bonding *bond = to_bond(d);
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800790
nikolay@redhat.com278b2082013-08-01 16:54:51 +0200791 return sprintf(buf, "%s\n", bond->curr_active_slave ? "up" : "down");
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800792}
Greg Kroah-Hartman43cb76d2002-04-09 12:14:34 -0700793static DEVICE_ATTR(mii_status, S_IRUGO, bonding_show_mii_status, NULL);
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800794
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800795/*
796 * Show current 802.3ad aggregator ID.
797 */
Greg Kroah-Hartman43cb76d2002-04-09 12:14:34 -0700798static ssize_t bonding_show_ad_aggregator(struct device *d,
799 struct device_attribute *attr,
800 char *buf)
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800801{
802 int count = 0;
Greg Kroah-Hartman43cb76d2002-04-09 12:14:34 -0700803 struct bonding *bond = to_bond(d);
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800804
805 if (bond->params.mode == BOND_MODE_8023AD) {
806 struct ad_info ad_info;
Stephen Hemminger3d632c32009-06-12 19:02:48 +0000807 count = sprintf(buf, "%d\n",
nikolay@redhat.com318debd2013-05-18 01:18:31 +0000808 bond_3ad_get_active_agg_info(bond, &ad_info)
Stephen Hemminger3d632c32009-06-12 19:02:48 +0000809 ? 0 : ad_info.aggregator_id);
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800810 }
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800811
812 return count;
813}
Greg Kroah-Hartman43cb76d2002-04-09 12:14:34 -0700814static DEVICE_ATTR(ad_aggregator, S_IRUGO, bonding_show_ad_aggregator, NULL);
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800815
816
817/*
818 * Show number of active 802.3ad ports.
819 */
Greg Kroah-Hartman43cb76d2002-04-09 12:14:34 -0700820static ssize_t bonding_show_ad_num_ports(struct device *d,
821 struct device_attribute *attr,
822 char *buf)
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800823{
824 int count = 0;
Greg Kroah-Hartman43cb76d2002-04-09 12:14:34 -0700825 struct bonding *bond = to_bond(d);
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800826
827 if (bond->params.mode == BOND_MODE_8023AD) {
828 struct ad_info ad_info;
Stephen Hemminger3d632c32009-06-12 19:02:48 +0000829 count = sprintf(buf, "%d\n",
nikolay@redhat.com318debd2013-05-18 01:18:31 +0000830 bond_3ad_get_active_agg_info(bond, &ad_info)
Stephen Hemminger3d632c32009-06-12 19:02:48 +0000831 ? 0 : ad_info.ports);
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800832 }
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800833
834 return count;
835}
Greg Kroah-Hartman43cb76d2002-04-09 12:14:34 -0700836static DEVICE_ATTR(ad_num_ports, S_IRUGO, bonding_show_ad_num_ports, NULL);
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800837
838
839/*
840 * Show current 802.3ad actor key.
841 */
Greg Kroah-Hartman43cb76d2002-04-09 12:14:34 -0700842static ssize_t bonding_show_ad_actor_key(struct device *d,
843 struct device_attribute *attr,
844 char *buf)
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800845{
846 int count = 0;
Greg Kroah-Hartman43cb76d2002-04-09 12:14:34 -0700847 struct bonding *bond = to_bond(d);
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800848
849 if (bond->params.mode == BOND_MODE_8023AD) {
850 struct ad_info ad_info;
Stephen Hemminger3d632c32009-06-12 19:02:48 +0000851 count = sprintf(buf, "%d\n",
nikolay@redhat.com318debd2013-05-18 01:18:31 +0000852 bond_3ad_get_active_agg_info(bond, &ad_info)
Stephen Hemminger3d632c32009-06-12 19:02:48 +0000853 ? 0 : ad_info.actor_key);
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800854 }
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800855
856 return count;
857}
Greg Kroah-Hartman43cb76d2002-04-09 12:14:34 -0700858static DEVICE_ATTR(ad_actor_key, S_IRUGO, bonding_show_ad_actor_key, NULL);
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800859
860
861/*
862 * Show current 802.3ad partner key.
863 */
Greg Kroah-Hartman43cb76d2002-04-09 12:14:34 -0700864static ssize_t bonding_show_ad_partner_key(struct device *d,
865 struct device_attribute *attr,
866 char *buf)
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800867{
868 int count = 0;
Greg Kroah-Hartman43cb76d2002-04-09 12:14:34 -0700869 struct bonding *bond = to_bond(d);
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800870
871 if (bond->params.mode == BOND_MODE_8023AD) {
872 struct ad_info ad_info;
Stephen Hemminger3d632c32009-06-12 19:02:48 +0000873 count = sprintf(buf, "%d\n",
nikolay@redhat.com318debd2013-05-18 01:18:31 +0000874 bond_3ad_get_active_agg_info(bond, &ad_info)
Stephen Hemminger3d632c32009-06-12 19:02:48 +0000875 ? 0 : ad_info.partner_key);
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800876 }
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800877
878 return count;
879}
Greg Kroah-Hartman43cb76d2002-04-09 12:14:34 -0700880static DEVICE_ATTR(ad_partner_key, S_IRUGO, bonding_show_ad_partner_key, NULL);
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800881
882
883/*
884 * Show current 802.3ad partner mac.
885 */
Greg Kroah-Hartman43cb76d2002-04-09 12:14:34 -0700886static ssize_t bonding_show_ad_partner_mac(struct device *d,
887 struct device_attribute *attr,
888 char *buf)
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800889{
890 int count = 0;
Greg Kroah-Hartman43cb76d2002-04-09 12:14:34 -0700891 struct bonding *bond = to_bond(d);
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800892
893 if (bond->params.mode == BOND_MODE_8023AD) {
894 struct ad_info ad_info;
Stephen Hemminger3d632c32009-06-12 19:02:48 +0000895 if (!bond_3ad_get_active_agg_info(bond, &ad_info))
Johannes Berge1749612008-10-27 15:59:26 -0700896 count = sprintf(buf, "%pM\n", ad_info.partner_system);
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800897 }
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800898
899 return count;
900}
Greg Kroah-Hartman43cb76d2002-04-09 12:14:34 -0700901static DEVICE_ATTR(ad_partner_mac, S_IRUGO, bonding_show_ad_partner_mac, NULL);
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800902
Andy Gospodarekebd8e492010-06-02 08:39:21 +0000903/*
Andy Gospodarekbb1d9122010-06-02 08:40:18 +0000904 * Show the queue_ids of the slaves in the current bond.
905 */
906static ssize_t bonding_show_queue_id(struct device *d,
907 struct device_attribute *attr,
908 char *buf)
909{
Andy Gospodarekbb1d9122010-06-02 08:40:18 +0000910 struct bonding *bond = to_bond(d);
Veaceslav Falico9caff1e2013-09-25 09:20:14 +0200911 struct list_head *iter;
nikolay@redhat.comdec1e902013-08-01 16:54:47 +0200912 struct slave *slave;
913 int res = 0;
Andy Gospodarekbb1d9122010-06-02 08:40:18 +0000914
915 if (!rtnl_trylock())
916 return restart_syscall();
917
Veaceslav Falico9caff1e2013-09-25 09:20:14 +0200918 bond_for_each_slave(bond, slave, iter) {
Nicolas de Pesloüan79236682010-07-14 18:24:54 -0700919 if (res > (PAGE_SIZE - IFNAMSIZ - 6)) {
920 /* not enough space for another interface_name:queue_id pair */
Andy Gospodarekbb1d9122010-06-02 08:40:18 +0000921 if ((PAGE_SIZE - res) > 10)
922 res = PAGE_SIZE - 10;
923 res += sprintf(buf + res, "++more++ ");
924 break;
925 }
926 res += sprintf(buf + res, "%s:%d ",
927 slave->dev->name, slave->queue_id);
928 }
Andy Gospodarekbb1d9122010-06-02 08:40:18 +0000929 if (res)
930 buf[res-1] = '\n'; /* eat the leftover space */
dingtianhong4d1ae5f2013-10-15 16:28:42 +0800931
Andy Gospodarekbb1d9122010-06-02 08:40:18 +0000932 rtnl_unlock();
nikolay@redhat.comdec1e902013-08-01 16:54:47 +0200933
Andy Gospodarekbb1d9122010-06-02 08:40:18 +0000934 return res;
935}
936
937/*
938 * Set the queue_ids of the slaves in the current bond. The bond
939 * interface must be enslaved for this to work.
940 */
941static ssize_t bonding_store_queue_id(struct device *d,
942 struct device_attribute *attr,
943 const char *buffer, size_t count)
944{
Andy Gospodarekbb1d9122010-06-02 08:40:18 +0000945 struct bonding *bond = to_bond(d);
Nikolay Aleksandrov24089ba2014-01-22 14:53:36 +0100946 int ret;
Andy Gospodarekbb1d9122010-06-02 08:40:18 +0000947
Nikolay Aleksandrov24089ba2014-01-22 14:53:36 +0100948 ret = bond_opt_tryset_rtnl(bond, BOND_OPT_QUEUE_ID, (char *)buffer);
949 if (!ret)
950 ret = count;
Andy Gospodarekbb1d9122010-06-02 08:40:18 +0000951
Andy Gospodarekbb1d9122010-06-02 08:40:18 +0000952 return ret;
Andy Gospodarekbb1d9122010-06-02 08:40:18 +0000953}
Andy Gospodarekbb1d9122010-06-02 08:40:18 +0000954static DEVICE_ATTR(queue_id, S_IRUGO | S_IWUSR, bonding_show_queue_id,
955 bonding_store_queue_id);
956
957
958/*
Andy Gospodarekebd8e492010-06-02 08:39:21 +0000959 * Show and set the all_slaves_active flag.
960 */
961static ssize_t bonding_show_slaves_active(struct device *d,
962 struct device_attribute *attr,
963 char *buf)
964{
965 struct bonding *bond = to_bond(d);
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800966
Andy Gospodarekebd8e492010-06-02 08:39:21 +0000967 return sprintf(buf, "%d\n", bond->params.all_slaves_active);
968}
969
970static ssize_t bonding_store_slaves_active(struct device *d,
971 struct device_attribute *attr,
972 const char *buf, size_t count)
973{
Andy Gospodarekebd8e492010-06-02 08:39:21 +0000974 struct bonding *bond = to_bond(d);
Nikolay Aleksandrov3df01162014-01-22 14:53:37 +0100975 int ret;
dingtianhong4d1ae5f2013-10-15 16:28:42 +0800976
Nikolay Aleksandrov3df01162014-01-22 14:53:37 +0100977 ret = bond_opt_tryset_rtnl(bond, BOND_OPT_ALL_SLAVES_ACTIVE,
978 (char *)buf);
sfeldma@cumulusnetworks.com1cc0b1e2013-12-17 21:30:16 -0800979 if (!ret)
980 ret = count;
Andy Gospodarekebd8e492010-06-02 08:39:21 +0000981
Jiri Pirko672bda32011-01-25 11:03:25 +0000982 return ret;
Andy Gospodarekebd8e492010-06-02 08:39:21 +0000983}
984static DEVICE_ATTR(all_slaves_active, S_IRUGO | S_IWUSR,
985 bonding_show_slaves_active, bonding_store_slaves_active);
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800986
Flavio Leitnerc2952c32010-10-05 14:23:59 +0000987/*
988 * Show and set the number of IGMP membership reports to send on link failure
989 */
990static ssize_t bonding_show_resend_igmp(struct device *d,
Flavio Leitner94265cf2011-05-25 08:38:58 +0000991 struct device_attribute *attr,
992 char *buf)
Flavio Leitnerc2952c32010-10-05 14:23:59 +0000993{
994 struct bonding *bond = to_bond(d);
995
996 return sprintf(buf, "%d\n", bond->params.resend_igmp);
997}
998
999static ssize_t bonding_store_resend_igmp(struct device *d,
Flavio Leitner94265cf2011-05-25 08:38:58 +00001000 struct device_attribute *attr,
1001 const char *buf, size_t count)
Flavio Leitnerc2952c32010-10-05 14:23:59 +00001002{
Flavio Leitnerc2952c32010-10-05 14:23:59 +00001003 struct bonding *bond = to_bond(d);
Nikolay Aleksandrov105c8fb2014-01-22 14:53:38 +01001004 int ret;
Flavio Leitnerc2952c32010-10-05 14:23:59 +00001005
Nikolay Aleksandrov105c8fb2014-01-22 14:53:38 +01001006 ret = bond_opt_tryset_rtnl(bond, BOND_OPT_RESEND_IGMP, (char *)buf);
sfeldma@cumulusnetworks.comd8838de72013-12-15 16:42:19 -08001007 if (!ret)
1008 ret = count;
1009
Flavio Leitnerc2952c32010-10-05 14:23:59 +00001010 return ret;
1011}
1012
1013static DEVICE_ATTR(resend_igmp, S_IRUGO | S_IWUSR,
1014 bonding_show_resend_igmp, bonding_store_resend_igmp);
1015
Neil Horman7eacd032013-09-13 11:05:33 -04001016
1017static ssize_t bonding_show_lp_interval(struct device *d,
1018 struct device_attribute *attr,
1019 char *buf)
1020{
1021 struct bonding *bond = to_bond(d);
1022 return sprintf(buf, "%d\n", bond->params.lp_interval);
1023}
1024
1025static ssize_t bonding_store_lp_interval(struct device *d,
1026 struct device_attribute *attr,
1027 const char *buf, size_t count)
1028{
1029 struct bonding *bond = to_bond(d);
Nikolay Aleksandrov4325b372014-01-22 14:53:39 +01001030 int ret;
Neil Horman7eacd032013-09-13 11:05:33 -04001031
Nikolay Aleksandrov4325b372014-01-22 14:53:39 +01001032 ret = bond_opt_tryset_rtnl(bond, BOND_OPT_LP_INTERVAL, (char *)buf);
sfeldma@cumulusnetworks.com8d836d02013-12-17 21:30:30 -08001033 if (!ret)
1034 ret = count;
1035
Neil Horman7eacd032013-09-13 11:05:33 -04001036 return ret;
1037}
1038
1039static DEVICE_ATTR(lp_interval, S_IRUGO | S_IWUSR,
1040 bonding_show_lp_interval, bonding_store_lp_interval);
1041
Nikolay Aleksandrov73958322013-11-05 13:51:41 +01001042static ssize_t bonding_show_packets_per_slave(struct device *d,
1043 struct device_attribute *attr,
1044 char *buf)
1045{
1046 struct bonding *bond = to_bond(d);
Nikolay Aleksandrova752a8b2013-12-05 11:36:58 +01001047 unsigned int packets_per_slave = bond->params.packets_per_slave;
Nikolay Aleksandrova752a8b2013-12-05 11:36:58 +01001048 return sprintf(buf, "%u\n", packets_per_slave);
Nikolay Aleksandrov73958322013-11-05 13:51:41 +01001049}
1050
1051static ssize_t bonding_store_packets_per_slave(struct device *d,
1052 struct device_attribute *attr,
1053 const char *buf, size_t count)
1054{
1055 struct bonding *bond = to_bond(d);
Nikolay Aleksandrovaa59d852014-01-22 14:53:18 +01001056 int ret;
Nikolay Aleksandrov73958322013-11-05 13:51:41 +01001057
Nikolay Aleksandrovaa59d852014-01-22 14:53:18 +01001058 ret = bond_opt_tryset_rtnl(bond, BOND_OPT_PACKETS_PER_SLAVE,
1059 (char *)buf);
sfeldma@cumulusnetworks.comc13ab3f2013-12-17 21:30:37 -08001060 if (!ret)
1061 ret = count;
1062
Nikolay Aleksandrov73958322013-11-05 13:51:41 +01001063 return ret;
1064}
1065
1066static DEVICE_ATTR(packets_per_slave, S_IRUGO | S_IWUSR,
1067 bonding_show_packets_per_slave,
1068 bonding_store_packets_per_slave);
1069
Mitch Williamsb76cdba2005-11-09 10:36:41 -08001070static struct attribute *per_bond_attrs[] = {
Greg Kroah-Hartman43cb76d2002-04-09 12:14:34 -07001071 &dev_attr_slaves.attr,
1072 &dev_attr_mode.attr,
Jay Vosburghdd957c52007-10-09 19:57:24 -07001073 &dev_attr_fail_over_mac.attr,
Greg Kroah-Hartman43cb76d2002-04-09 12:14:34 -07001074 &dev_attr_arp_validate.attr,
Veaceslav Falico8599b522013-06-24 11:49:34 +02001075 &dev_attr_arp_all_targets.attr,
Greg Kroah-Hartman43cb76d2002-04-09 12:14:34 -07001076 &dev_attr_arp_interval.attr,
1077 &dev_attr_arp_ip_target.attr,
1078 &dev_attr_downdelay.attr,
1079 &dev_attr_updelay.attr,
1080 &dev_attr_lacp_rate.attr,
Jay Vosburghfd989c82008-11-04 17:51:16 -08001081 &dev_attr_ad_select.attr,
Greg Kroah-Hartman43cb76d2002-04-09 12:14:34 -07001082 &dev_attr_xmit_hash_policy.attr,
Ben Hutchingsad246c92011-04-26 15:25:52 +00001083 &dev_attr_num_grat_arp.attr,
1084 &dev_attr_num_unsol_na.attr,
Greg Kroah-Hartman43cb76d2002-04-09 12:14:34 -07001085 &dev_attr_miimon.attr,
1086 &dev_attr_primary.attr,
Jiri Pirkoa5499522009-09-25 03:28:09 +00001087 &dev_attr_primary_reselect.attr,
Greg Kroah-Hartman43cb76d2002-04-09 12:14:34 -07001088 &dev_attr_use_carrier.attr,
1089 &dev_attr_active_slave.attr,
1090 &dev_attr_mii_status.attr,
1091 &dev_attr_ad_aggregator.attr,
1092 &dev_attr_ad_num_ports.attr,
1093 &dev_attr_ad_actor_key.attr,
1094 &dev_attr_ad_partner_key.attr,
1095 &dev_attr_ad_partner_mac.attr,
Andy Gospodarekbb1d9122010-06-02 08:40:18 +00001096 &dev_attr_queue_id.attr,
Andy Gospodarekebd8e492010-06-02 08:39:21 +00001097 &dev_attr_all_slaves_active.attr,
Flavio Leitnerc2952c32010-10-05 14:23:59 +00001098 &dev_attr_resend_igmp.attr,
stephen hemminger655f8912011-06-22 09:54:39 +00001099 &dev_attr_min_links.attr,
Neil Horman7eacd032013-09-13 11:05:33 -04001100 &dev_attr_lp_interval.attr,
Nikolay Aleksandrov73958322013-11-05 13:51:41 +01001101 &dev_attr_packets_per_slave.attr,
Mitch Williamsb76cdba2005-11-09 10:36:41 -08001102 NULL,
1103};
1104
1105static struct attribute_group bonding_group = {
1106 .name = "bonding",
1107 .attrs = per_bond_attrs,
1108};
1109
1110/*
1111 * Initialize sysfs. This sets up the bonding_masters file in
1112 * /sys/class/net.
1113 */
Eric W. Biederman4c224002011-10-12 21:56:25 +00001114int bond_create_sysfs(struct bond_net *bn)
Mitch Williamsb76cdba2005-11-09 10:36:41 -08001115{
Jay Vosburghb8a97872008-06-13 18:12:04 -07001116 int ret;
Mitch Williamsb76cdba2005-11-09 10:36:41 -08001117
Eric W. Biederman4c224002011-10-12 21:56:25 +00001118 bn->class_attr_bonding_masters = class_attr_bonding_masters;
Eric W. Biederman01718e32011-10-21 22:43:07 +00001119 sysfs_attr_init(&bn->class_attr_bonding_masters.attr);
Eric W. Biederman4c224002011-10-12 21:56:25 +00001120
Tejun Heo58292cbe2013-09-11 22:29:04 -04001121 ret = netdev_class_create_file_ns(&bn->class_attr_bonding_masters,
1122 bn->net);
Jay Vosburgh877cbd32007-01-19 18:15:47 -08001123 /*
1124 * Permit multiple loads of the module by ignoring failures to
1125 * create the bonding_masters sysfs file. Bonding devices
1126 * created by second or subsequent loads of the module will
1127 * not be listed in, or controllable by, bonding_masters, but
1128 * will have the usual "bonding" sysfs directory.
1129 *
1130 * This is done to preserve backwards compatibility for
1131 * initscripts/sysconfig, which load bonding multiple times to
1132 * configure multiple bonding devices.
1133 */
1134 if (ret == -EEXIST) {
Stephen Hemminger38d2f382008-05-14 22:35:04 -07001135 /* Is someone being kinky and naming a device bonding_master? */
Eric W. Biederman4c224002011-10-12 21:56:25 +00001136 if (__dev_get_by_name(bn->net,
Stephen Hemminger38d2f382008-05-14 22:35:04 -07001137 class_attr_bonding_masters.attr.name))
Joe Perches90194262014-02-15 16:01:45 -08001138 pr_err("network device named %s already exists in sysfs\n",
Stephen Hemminger38d2f382008-05-14 22:35:04 -07001139 class_attr_bonding_masters.attr.name);
Stephen Hemminger130aa612009-06-11 05:46:04 -07001140 ret = 0;
Jay Vosburgh877cbd32007-01-19 18:15:47 -08001141 }
Mitch Williamsb76cdba2005-11-09 10:36:41 -08001142
1143 return ret;
1144
1145}
1146
1147/*
1148 * Remove /sys/class/net/bonding_masters.
1149 */
Eric W. Biederman4c224002011-10-12 21:56:25 +00001150void bond_destroy_sysfs(struct bond_net *bn)
Mitch Williamsb76cdba2005-11-09 10:36:41 -08001151{
Tejun Heo58292cbe2013-09-11 22:29:04 -04001152 netdev_class_remove_file_ns(&bn->class_attr_bonding_masters, bn->net);
Mitch Williamsb76cdba2005-11-09 10:36:41 -08001153}
1154
1155/*
1156 * Initialize sysfs for each bond. This sets up and registers
1157 * the 'bondctl' directory for each individual bond under /sys/class/net.
1158 */
Eric W. Biederman6151b3d2009-10-29 14:18:22 +00001159void bond_prepare_sysfs_group(struct bonding *bond)
Mitch Williamsb76cdba2005-11-09 10:36:41 -08001160{
Eric W. Biederman6151b3d2009-10-29 14:18:22 +00001161 bond->dev->sysfs_groups[0] = &bonding_group;
Mitch Williamsb76cdba2005-11-09 10:36:41 -08001162}
1163