blob: 5555517284db6916ce4982684776376d37e768b5 [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
Nikolay Aleksandrovdc3e5d12014-05-08 14:23:54 +020048/* "show" function for the bond_masters attribute.
Mitch Williamsb76cdba2005-11-09 10:36:41 -080049 * The class parameter is ignored.
50 */
Andi Kleen28812fe2010-01-05 12:48:07 +010051static ssize_t bonding_show_bonds(struct class *cls,
52 struct class_attribute *attr,
53 char *buf)
Mitch Williamsb76cdba2005-11-09 10:36:41 -080054{
Eric W. Biederman4c224002011-10-12 21:56:25 +000055 struct bond_net *bn =
56 container_of(attr, struct bond_net, class_attr_bonding_masters);
Mitch Williamsb76cdba2005-11-09 10:36:41 -080057 int res = 0;
58 struct bonding *bond;
59
Stephen Hemminger7e083842009-06-12 19:02:46 +000060 rtnl_lock();
Mitch Williamsb76cdba2005-11-09 10:36:41 -080061
Eric W. Biedermanec87fd32009-10-29 14:18:26 +000062 list_for_each_entry(bond, &bn->dev_list, bond_list) {
Mitch Williamsb76cdba2005-11-09 10:36:41 -080063 if (res > (PAGE_SIZE - IFNAMSIZ)) {
64 /* not enough space for another interface name */
65 if ((PAGE_SIZE - res) > 10)
66 res = PAGE_SIZE - 10;
Wagner Ferencb8843662007-12-06 23:40:30 -080067 res += sprintf(buf + res, "++more++ ");
Mitch Williamsb76cdba2005-11-09 10:36:41 -080068 break;
69 }
Wagner Ferencb8843662007-12-06 23:40:30 -080070 res += sprintf(buf + res, "%s ", bond->dev->name);
Mitch Williamsb76cdba2005-11-09 10:36:41 -080071 }
Wagner Ferenc1dcdcd62007-12-06 23:40:31 -080072 if (res)
73 buf[res-1] = '\n'; /* eat the leftover space */
Stephen Hemminger7e083842009-06-12 19:02:46 +000074
75 rtnl_unlock();
Mitch Williamsb76cdba2005-11-09 10:36:41 -080076 return res;
77}
78
Eric W. Biederman4c224002011-10-12 21:56:25 +000079static struct net_device *bond_get_by_name(struct bond_net *bn, const char *ifname)
Stephen Hemminger373500d2009-06-12 19:02:50 +000080{
81 struct bonding *bond;
82
Eric W. Biedermanec87fd32009-10-29 14:18:26 +000083 list_for_each_entry(bond, &bn->dev_list, bond_list) {
Stephen Hemminger373500d2009-06-12 19:02:50 +000084 if (strncmp(bond->dev->name, ifname, IFNAMSIZ) == 0)
85 return bond->dev;
86 }
87 return NULL;
88}
89
Nikolay Aleksandrovdc3e5d12014-05-08 14:23:54 +020090/* "store" function for the bond_masters attribute. This is what
Mitch Williamsb76cdba2005-11-09 10:36:41 -080091 * creates and deletes entire bonds.
92 *
93 * The class parameter is ignored.
94 *
95 */
Stephen Hemminger3d632c32009-06-12 19:02:48 +000096static ssize_t bonding_store_bonds(struct class *cls,
Andi Kleen28812fe2010-01-05 12:48:07 +010097 struct class_attribute *attr,
Stephen Hemminger3d632c32009-06-12 19:02:48 +000098 const char *buffer, size_t count)
Mitch Williamsb76cdba2005-11-09 10:36:41 -080099{
Eric W. Biederman4c224002011-10-12 21:56:25 +0000100 struct bond_net *bn =
101 container_of(attr, struct bond_net, class_attr_bonding_masters);
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800102 char command[IFNAMSIZ + 1] = {0, };
103 char *ifname;
Jay Vosburgh027ea042008-01-17 16:25:02 -0800104 int rv, res = count;
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800105
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800106 sscanf(buffer, "%16s", command); /* IFNAMSIZ*/
107 ifname = command + 1;
108 if ((strlen(command) <= 1) ||
109 !dev_valid_name(ifname))
110 goto err_no_cmd;
111
112 if (command[0] == '+') {
Joe Perchesa4aee5c2009-12-13 20:06:07 -0800113 pr_info("%s is being created...\n", ifname);
Eric W. Biederman4c224002011-10-12 21:56:25 +0000114 rv = bond_create(bn->net, ifname);
Jay Vosburgh027ea042008-01-17 16:25:02 -0800115 if (rv) {
Phil Oester5f86cad12011-03-14 06:22:06 +0000116 if (rv == -EEXIST)
Joe Perches90194262014-02-15 16:01:45 -0800117 pr_info("%s already exists\n", ifname);
Phil Oester5f86cad12011-03-14 06:22:06 +0000118 else
Joe Perches90194262014-02-15 16:01:45 -0800119 pr_info("%s creation failed\n", ifname);
Jay Vosburgh027ea042008-01-17 16:25:02 -0800120 res = rv;
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800121 }
Stephen Hemminger373500d2009-06-12 19:02:50 +0000122 } else if (command[0] == '-') {
123 struct net_device *bond_dev;
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800124
Jay Vosburgh027ea042008-01-17 16:25:02 -0800125 rtnl_lock();
Eric W. Biederman4c224002011-10-12 21:56:25 +0000126 bond_dev = bond_get_by_name(bn, ifname);
Stephen Hemminger373500d2009-06-12 19:02:50 +0000127 if (bond_dev) {
Joe Perchesa4aee5c2009-12-13 20:06:07 -0800128 pr_info("%s is being deleted...\n", ifname);
Stephen Hemminger373500d2009-06-12 19:02:50 +0000129 unregister_netdevice(bond_dev);
130 } else {
Joe Perchesa4aee5c2009-12-13 20:06:07 -0800131 pr_err("unable to delete non-existent %s\n", ifname);
Stephen Hemminger373500d2009-06-12 19:02:50 +0000132 res = -ENODEV;
133 }
134 rtnl_unlock();
135 } else
136 goto err_no_cmd;
Jay Vosburgh027ea042008-01-17 16:25:02 -0800137
Stephen Hemminger373500d2009-06-12 19:02:50 +0000138 /* Always return either count or an error. If you return 0, you'll
139 * get called forever, which is bad.
140 */
141 return res;
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800142
143err_no_cmd:
Joe Perches90194262014-02-15 16:01:45 -0800144 pr_err("no command found in bonding_masters - use +ifname or -ifname\n");
Jay Vosburghc4ebc662008-05-02 17:49:38 -0700145 return -EPERM;
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800146}
Stephen Hemminger373500d2009-06-12 19:02:50 +0000147
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800148/* class attribute for bond_masters file. This ends up in /sys/class/net */
Eric W. Biederman4c224002011-10-12 21:56:25 +0000149static const struct class_attribute class_attr_bonding_masters = {
150 .attr = {
151 .name = "bonding_masters",
152 .mode = S_IWUSR | S_IRUGO,
153 },
154 .show = bonding_show_bonds,
155 .store = bonding_store_bonds,
Eric W. Biederman4c224002011-10-12 21:56:25 +0000156};
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800157
Nikolay Aleksandrovdc3e5d12014-05-08 14:23:54 +0200158/* Generic "store" method for bonding sysfs option setting */
159static ssize_t bonding_sysfs_store_option(struct device *d,
160 struct device_attribute *attr,
161 const char *buffer, size_t count)
162{
163 struct bonding *bond = to_bond(d);
164 const struct bond_option *opt;
165 int ret;
166
167 opt = bond_opt_get_by_name(attr->attr.name);
168 if (WARN_ON(!opt))
169 return -ENOENT;
170 ret = bond_opt_tryset_rtnl(bond, opt->id, (char *)buffer);
171 if (!ret)
172 ret = count;
173
174 return ret;
175}
176
177/* Show the slaves in the current bond. */
Greg Kroah-Hartman43cb76d2002-04-09 12:14:34 -0700178static ssize_t bonding_show_slaves(struct device *d,
179 struct device_attribute *attr, char *buf)
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800180{
Greg Kroah-Hartman43cb76d2002-04-09 12:14:34 -0700181 struct bonding *bond = to_bond(d);
Veaceslav Falico9caff1e2013-09-25 09:20:14 +0200182 struct list_head *iter;
nikolay@redhat.comdec1e902013-08-01 16:54:47 +0200183 struct slave *slave;
184 int res = 0;
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800185
dingtianhong4d1ae5f2013-10-15 16:28:42 +0800186 if (!rtnl_trylock())
187 return restart_syscall();
188
Veaceslav Falico9caff1e2013-09-25 09:20:14 +0200189 bond_for_each_slave(bond, slave, iter) {
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800190 if (res > (PAGE_SIZE - IFNAMSIZ)) {
191 /* not enough space for another interface name */
192 if ((PAGE_SIZE - res) > 10)
193 res = PAGE_SIZE - 10;
Wagner Ferenc7bd46502007-12-06 23:40:28 -0800194 res += sprintf(buf + res, "++more++ ");
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800195 break;
196 }
197 res += sprintf(buf + res, "%s ", slave->dev->name);
198 }
dingtianhong4d1ae5f2013-10-15 16:28:42 +0800199
200 rtnl_unlock();
201
Wagner Ferenc1dcdcd62007-12-06 23:40:31 -0800202 if (res)
203 buf[res-1] = '\n'; /* eat the leftover space */
nikolay@redhat.comdec1e902013-08-01 16:54:47 +0200204
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800205 return res;
206}
Stephen Hemminger3d632c32009-06-12 19:02:48 +0000207static DEVICE_ATTR(slaves, S_IRUGO | S_IWUSR, bonding_show_slaves,
Nikolay Aleksandrovdc3e5d12014-05-08 14:23:54 +0200208 bonding_sysfs_store_option);
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800209
Nikolay Aleksandrovdc3e5d12014-05-08 14:23:54 +0200210/* Show the bonding mode. */
Greg Kroah-Hartman43cb76d2002-04-09 12:14:34 -0700211static ssize_t bonding_show_mode(struct device *d,
212 struct device_attribute *attr, char *buf)
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800213{
Greg Kroah-Hartman43cb76d2002-04-09 12:14:34 -0700214 struct bonding *bond = to_bond(d);
stephen hemmingerf3253332014-03-04 16:36:44 -0800215 const struct bond_opt_value *val;
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800216
Veaceslav Falico01844092014-05-15 21:39:55 +0200217 val = bond_opt_get_val(BOND_OPT_MODE, BOND_MODE(bond));
Nikolay Aleksandrov2b3798d2014-01-22 14:53:17 +0100218
Veaceslav Falico01844092014-05-15 21:39:55 +0200219 return sprintf(buf, "%s %d\n", val->string, BOND_MODE(bond));
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800220}
Stephen Hemminger3d632c32009-06-12 19:02:48 +0000221static DEVICE_ATTR(mode, S_IRUGO | S_IWUSR,
Nikolay Aleksandrovdc3e5d12014-05-08 14:23:54 +0200222 bonding_show_mode, bonding_sysfs_store_option);
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800223
Nikolay Aleksandrovdc3e5d12014-05-08 14:23:54 +0200224/* Show the bonding transmit hash method. */
Greg Kroah-Hartman43cb76d2002-04-09 12:14:34 -0700225static ssize_t bonding_show_xmit_hash(struct device *d,
226 struct device_attribute *attr,
227 char *buf)
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800228{
Greg Kroah-Hartman43cb76d2002-04-09 12:14:34 -0700229 struct bonding *bond = to_bond(d);
stephen hemmingerf3253332014-03-04 16:36:44 -0800230 const struct bond_opt_value *val;
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800231
Nikolay Aleksandrova4b32ce2014-01-22 14:53:19 +0100232 val = bond_opt_get_val(BOND_OPT_XMIT_HASH, bond->params.xmit_policy);
233
234 return sprintf(buf, "%s %d\n", val->string, bond->params.xmit_policy);
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800235}
Stephen Hemminger3d632c32009-06-12 19:02:48 +0000236static DEVICE_ATTR(xmit_hash_policy, S_IRUGO | S_IWUSR,
Nikolay Aleksandrovdc3e5d12014-05-08 14:23:54 +0200237 bonding_show_xmit_hash, bonding_sysfs_store_option);
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800238
Nikolay Aleksandrovdc3e5d12014-05-08 14:23:54 +0200239/* Show arp_validate. */
Greg Kroah-Hartman43cb76d2002-04-09 12:14:34 -0700240static ssize_t bonding_show_arp_validate(struct device *d,
241 struct device_attribute *attr,
242 char *buf)
Jay Vosburghf5b2b962006-09-22 21:54:53 -0700243{
Greg Kroah-Hartman43cb76d2002-04-09 12:14:34 -0700244 struct bonding *bond = to_bond(d);
stephen hemmingerf3253332014-03-04 16:36:44 -0800245 const struct bond_opt_value *val;
Jay Vosburghf5b2b962006-09-22 21:54:53 -0700246
Nikolay Aleksandrov16228882014-01-22 14:53:20 +0100247 val = bond_opt_get_val(BOND_OPT_ARP_VALIDATE,
248 bond->params.arp_validate);
249
250 return sprintf(buf, "%s %d\n", val->string, bond->params.arp_validate);
Jay Vosburghf5b2b962006-09-22 21:54:53 -0700251}
Stephen Hemminger3d632c32009-06-12 19:02:48 +0000252static DEVICE_ATTR(arp_validate, S_IRUGO | S_IWUSR, bonding_show_arp_validate,
Nikolay Aleksandrovdc3e5d12014-05-08 14:23:54 +0200253 bonding_sysfs_store_option);
254
255/* Show arp_all_targets. */
Veaceslav Falico8599b522013-06-24 11:49:34 +0200256static ssize_t bonding_show_arp_all_targets(struct device *d,
257 struct device_attribute *attr,
258 char *buf)
259{
260 struct bonding *bond = to_bond(d);
stephen hemmingerf3253332014-03-04 16:36:44 -0800261 const struct bond_opt_value *val;
Veaceslav Falico8599b522013-06-24 11:49:34 +0200262
Nikolay Aleksandrovedf36b22014-01-22 14:53:21 +0100263 val = bond_opt_get_val(BOND_OPT_ARP_ALL_TARGETS,
264 bond->params.arp_all_targets);
265 return sprintf(buf, "%s %d\n",
266 val->string, bond->params.arp_all_targets);
Veaceslav Falico8599b522013-06-24 11:49:34 +0200267}
Veaceslav Falico8599b522013-06-24 11:49:34 +0200268static DEVICE_ATTR(arp_all_targets, S_IRUGO | S_IWUSR,
Nikolay Aleksandrovdc3e5d12014-05-08 14:23:54 +0200269 bonding_show_arp_all_targets, bonding_sysfs_store_option);
Jay Vosburghf5b2b962006-09-22 21:54:53 -0700270
Nikolay Aleksandrovdc3e5d12014-05-08 14:23:54 +0200271/* Show fail_over_mac. */
Stephen Hemminger3d632c32009-06-12 19:02:48 +0000272static ssize_t bonding_show_fail_over_mac(struct device *d,
273 struct device_attribute *attr,
274 char *buf)
Jay Vosburghdd957c52007-10-09 19:57:24 -0700275{
276 struct bonding *bond = to_bond(d);
stephen hemmingerf3253332014-03-04 16:36:44 -0800277 const struct bond_opt_value *val;
Jay Vosburghdd957c52007-10-09 19:57:24 -0700278
Nikolay Aleksandrov1df6b6a2014-01-22 14:53:22 +0100279 val = bond_opt_get_val(BOND_OPT_FAIL_OVER_MAC,
280 bond->params.fail_over_mac);
281
282 return sprintf(buf, "%s %d\n", val->string, bond->params.fail_over_mac);
Jay Vosburghdd957c52007-10-09 19:57:24 -0700283}
Stephen Hemminger3d632c32009-06-12 19:02:48 +0000284static DEVICE_ATTR(fail_over_mac, S_IRUGO | S_IWUSR,
Nikolay Aleksandrovdc3e5d12014-05-08 14:23:54 +0200285 bonding_show_fail_over_mac, bonding_sysfs_store_option);
Jay Vosburghdd957c52007-10-09 19:57:24 -0700286
Nikolay Aleksandrovdc3e5d12014-05-08 14:23:54 +0200287/* Show the arp timer interval. */
Greg Kroah-Hartman43cb76d2002-04-09 12:14:34 -0700288static ssize_t bonding_show_arp_interval(struct device *d,
289 struct device_attribute *attr,
290 char *buf)
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800291{
Greg Kroah-Hartman43cb76d2002-04-09 12:14:34 -0700292 struct bonding *bond = to_bond(d);
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800293
Wagner Ferenc7bd46502007-12-06 23:40:28 -0800294 return sprintf(buf, "%d\n", bond->params.arp_interval);
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800295}
Stephen Hemminger3d632c32009-06-12 19:02:48 +0000296static DEVICE_ATTR(arp_interval, S_IRUGO | S_IWUSR,
Nikolay Aleksandrovdc3e5d12014-05-08 14:23:54 +0200297 bonding_show_arp_interval, bonding_sysfs_store_option);
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800298
Nikolay Aleksandrovdc3e5d12014-05-08 14:23:54 +0200299/* Show the arp targets. */
Greg Kroah-Hartman43cb76d2002-04-09 12:14:34 -0700300static ssize_t bonding_show_arp_targets(struct device *d,
301 struct device_attribute *attr,
302 char *buf)
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800303{
Greg Kroah-Hartman43cb76d2002-04-09 12:14:34 -0700304 struct bonding *bond = to_bond(d);
Nikolay Aleksandrov4fb0ef52014-01-22 14:53:24 +0100305 int i, res = 0;
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800306
307 for (i = 0; i < BOND_MAX_ARP_TARGETS; i++) {
308 if (bond->params.arp_targets[i])
Harvey Harrison63779432008-10-31 00:56:00 -0700309 res += sprintf(buf + res, "%pI4 ",
310 &bond->params.arp_targets[i]);
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800311 }
Wagner Ferenc1dcdcd62007-12-06 23:40:31 -0800312 if (res)
313 buf[res-1] = '\n'; /* eat the leftover space */
Nikolay Aleksandrov4fb0ef52014-01-22 14:53:24 +0100314
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800315 return res;
316}
Nikolay Aleksandrovdc3e5d12014-05-08 14:23:54 +0200317static DEVICE_ATTR(arp_ip_target, S_IRUGO | S_IWUSR,
318 bonding_show_arp_targets, bonding_sysfs_store_option);
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800319
Nikolay Aleksandrovdc3e5d12014-05-08 14:23:54 +0200320/* Show the up and down delays. */
Greg Kroah-Hartman43cb76d2002-04-09 12:14:34 -0700321static ssize_t bonding_show_downdelay(struct device *d,
322 struct device_attribute *attr,
323 char *buf)
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800324{
Greg Kroah-Hartman43cb76d2002-04-09 12:14:34 -0700325 struct bonding *bond = to_bond(d);
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800326
Wagner Ferenc7bd46502007-12-06 23:40:28 -0800327 return sprintf(buf, "%d\n", bond->params.downdelay * bond->params.miimon);
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800328}
Stephen Hemminger3d632c32009-06-12 19:02:48 +0000329static DEVICE_ATTR(downdelay, S_IRUGO | S_IWUSR,
Nikolay Aleksandrovdc3e5d12014-05-08 14:23:54 +0200330 bonding_show_downdelay, bonding_sysfs_store_option);
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800331
Greg Kroah-Hartman43cb76d2002-04-09 12:14:34 -0700332static ssize_t bonding_show_updelay(struct device *d,
333 struct device_attribute *attr,
334 char *buf)
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800335{
Greg Kroah-Hartman43cb76d2002-04-09 12:14:34 -0700336 struct bonding *bond = to_bond(d);
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800337
Wagner Ferenc7bd46502007-12-06 23:40:28 -0800338 return sprintf(buf, "%d\n", bond->params.updelay * bond->params.miimon);
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800339
340}
Stephen Hemminger3d632c32009-06-12 19:02:48 +0000341static DEVICE_ATTR(updelay, S_IRUGO | S_IWUSR,
Nikolay Aleksandrovdc3e5d12014-05-08 14:23:54 +0200342 bonding_show_updelay, bonding_sysfs_store_option);
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800343
Nikolay Aleksandrovdc3e5d12014-05-08 14:23:54 +0200344/* Show the LACP interval. */
Greg Kroah-Hartman43cb76d2002-04-09 12:14:34 -0700345static ssize_t bonding_show_lacp(struct device *d,
346 struct device_attribute *attr,
347 char *buf)
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800348{
Greg Kroah-Hartman43cb76d2002-04-09 12:14:34 -0700349 struct bonding *bond = to_bond(d);
stephen hemmingerf3253332014-03-04 16:36:44 -0800350 const struct bond_opt_value *val;
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800351
Nikolay Aleksandrovd3131de2014-01-22 14:53:27 +0100352 val = bond_opt_get_val(BOND_OPT_LACP_RATE, bond->params.lacp_fast);
353
354 return sprintf(buf, "%s %d\n", val->string, bond->params.lacp_fast);
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800355}
Stephen Hemminger3d632c32009-06-12 19:02:48 +0000356static DEVICE_ATTR(lacp_rate, S_IRUGO | S_IWUSR,
Nikolay Aleksandrovdc3e5d12014-05-08 14:23:54 +0200357 bonding_show_lacp, bonding_sysfs_store_option);
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800358
stephen hemminger655f8912011-06-22 09:54:39 +0000359static ssize_t bonding_show_min_links(struct device *d,
360 struct device_attribute *attr,
361 char *buf)
362{
363 struct bonding *bond = to_bond(d);
364
Masanari Iida014f1b22014-04-29 00:41:21 +0900365 return sprintf(buf, "%u\n", bond->params.min_links);
stephen hemminger655f8912011-06-22 09:54:39 +0000366}
stephen hemminger655f8912011-06-22 09:54:39 +0000367static DEVICE_ATTR(min_links, S_IRUGO | S_IWUSR,
Nikolay Aleksandrovdc3e5d12014-05-08 14:23:54 +0200368 bonding_show_min_links, bonding_sysfs_store_option);
stephen hemminger655f8912011-06-22 09:54:39 +0000369
Jay Vosburghfd989c82008-11-04 17:51:16 -0800370static ssize_t bonding_show_ad_select(struct device *d,
371 struct device_attribute *attr,
372 char *buf)
373{
374 struct bonding *bond = to_bond(d);
stephen hemmingerf3253332014-03-04 16:36:44 -0800375 const struct bond_opt_value *val;
Jay Vosburghfd989c82008-11-04 17:51:16 -0800376
Nikolay Aleksandrov9e5f5ee2014-01-22 14:53:29 +0100377 val = bond_opt_get_val(BOND_OPT_AD_SELECT, bond->params.ad_select);
378
379 return sprintf(buf, "%s %d\n", val->string, bond->params.ad_select);
Jay Vosburghfd989c82008-11-04 17:51:16 -0800380}
Stephen Hemminger3d632c32009-06-12 19:02:48 +0000381static DEVICE_ATTR(ad_select, S_IRUGO | S_IWUSR,
Nikolay Aleksandrovdc3e5d12014-05-08 14:23:54 +0200382 bonding_show_ad_select, bonding_sysfs_store_option);
Jay Vosburghfd989c82008-11-04 17:51:16 -0800383
Nikolay Aleksandrovdc3e5d12014-05-08 14:23:54 +0200384/* Show and set the number of peer notifications to send after a failover event. */
Ben Hutchingsad246c92011-04-26 15:25:52 +0000385static ssize_t bonding_show_num_peer_notif(struct device *d,
386 struct device_attribute *attr,
387 char *buf)
388{
389 struct bonding *bond = to_bond(d);
390 return sprintf(buf, "%d\n", bond->params.num_peer_notif);
391}
392
393static ssize_t bonding_store_num_peer_notif(struct device *d,
394 struct device_attribute *attr,
395 const char *buf, size_t count)
396{
397 struct bonding *bond = to_bond(d);
sfeldma@cumulusnetworks.com2c9839c2013-12-17 21:30:09 -0800398 int ret;
399
Nikolay Aleksandrovef56bec2014-01-22 14:53:30 +0100400 ret = bond_opt_tryset_rtnl(bond, BOND_OPT_NUM_PEER_NOTIF, (char *)buf);
sfeldma@cumulusnetworks.com2c9839c2013-12-17 21:30:09 -0800401 if (!ret)
402 ret = count;
403
sfeldma@cumulusnetworks.com2c9839c2013-12-17 21:30:09 -0800404 return ret;
Ben Hutchingsad246c92011-04-26 15:25:52 +0000405}
406static DEVICE_ATTR(num_grat_arp, S_IRUGO | S_IWUSR,
407 bonding_show_num_peer_notif, bonding_store_num_peer_notif);
408static DEVICE_ATTR(num_unsol_na, S_IRUGO | S_IWUSR,
409 bonding_show_num_peer_notif, bonding_store_num_peer_notif);
410
Nikolay Aleksandrovdc3e5d12014-05-08 14:23:54 +0200411/* Show the MII monitor interval. */
Greg Kroah-Hartman43cb76d2002-04-09 12:14:34 -0700412static ssize_t bonding_show_miimon(struct device *d,
413 struct device_attribute *attr,
414 char *buf)
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800415{
Greg Kroah-Hartman43cb76d2002-04-09 12:14:34 -0700416 struct bonding *bond = to_bond(d);
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800417
Wagner Ferenc7bd46502007-12-06 23:40:28 -0800418 return sprintf(buf, "%d\n", bond->params.miimon);
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800419}
Stephen Hemminger3d632c32009-06-12 19:02:48 +0000420static DEVICE_ATTR(miimon, S_IRUGO | S_IWUSR,
Nikolay Aleksandrovdc3e5d12014-05-08 14:23:54 +0200421 bonding_show_miimon, bonding_sysfs_store_option);
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800422
Nikolay Aleksandrovdc3e5d12014-05-08 14:23:54 +0200423/* Show the primary slave. */
Greg Kroah-Hartman43cb76d2002-04-09 12:14:34 -0700424static ssize_t bonding_show_primary(struct device *d,
425 struct device_attribute *attr,
426 char *buf)
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800427{
Greg Kroah-Hartman43cb76d2002-04-09 12:14:34 -0700428 struct bonding *bond = to_bond(d);
Nikolay Aleksandrov059b47e2014-09-09 23:17:00 +0200429 struct slave *primary;
430 int count = 0;
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800431
Nikolay Aleksandrov059b47e2014-09-09 23:17:00 +0200432 rcu_read_lock();
433 primary = rcu_dereference(bond->primary_slave);
434 if (primary)
435 count = sprintf(buf, "%s\n", primary->dev->name);
436 rcu_read_unlock();
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800437
438 return count;
439}
Stephen Hemminger3d632c32009-06-12 19:02:48 +0000440static DEVICE_ATTR(primary, S_IRUGO | S_IWUSR,
Nikolay Aleksandrovdc3e5d12014-05-08 14:23:54 +0200441 bonding_show_primary, bonding_sysfs_store_option);
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800442
Nikolay Aleksandrovdc3e5d12014-05-08 14:23:54 +0200443/* Show the primary_reselect flag. */
Jiri Pirkoa5499522009-09-25 03:28:09 +0000444static ssize_t bonding_show_primary_reselect(struct device *d,
445 struct device_attribute *attr,
446 char *buf)
447{
448 struct bonding *bond = to_bond(d);
stephen hemmingerf3253332014-03-04 16:36:44 -0800449 const struct bond_opt_value *val;
Nikolay Aleksandrov388d3a62014-01-22 14:53:33 +0100450
451 val = bond_opt_get_val(BOND_OPT_PRIMARY_RESELECT,
452 bond->params.primary_reselect);
Jiri Pirkoa5499522009-09-25 03:28:09 +0000453
454 return sprintf(buf, "%s %d\n",
Nikolay Aleksandrov388d3a62014-01-22 14:53:33 +0100455 val->string, bond->params.primary_reselect);
Jiri Pirkoa5499522009-09-25 03:28:09 +0000456}
Jiri Pirkoa5499522009-09-25 03:28:09 +0000457static DEVICE_ATTR(primary_reselect, S_IRUGO | S_IWUSR,
Nikolay Aleksandrovdc3e5d12014-05-08 14:23:54 +0200458 bonding_show_primary_reselect, bonding_sysfs_store_option);
Jiri Pirkoa5499522009-09-25 03:28:09 +0000459
Nikolay Aleksandrovdc3e5d12014-05-08 14:23:54 +0200460/* Show the use_carrier flag. */
Greg Kroah-Hartman43cb76d2002-04-09 12:14:34 -0700461static ssize_t bonding_show_carrier(struct device *d,
462 struct device_attribute *attr,
463 char *buf)
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800464{
Greg Kroah-Hartman43cb76d2002-04-09 12:14:34 -0700465 struct bonding *bond = to_bond(d);
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800466
Wagner Ferenc7bd46502007-12-06 23:40:28 -0800467 return sprintf(buf, "%d\n", bond->params.use_carrier);
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800468}
Stephen Hemminger3d632c32009-06-12 19:02:48 +0000469static DEVICE_ATTR(use_carrier, S_IRUGO | S_IWUSR,
Nikolay Aleksandrovdc3e5d12014-05-08 14:23:54 +0200470 bonding_show_carrier, bonding_sysfs_store_option);
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800471
472
Nikolay Aleksandrovdc3e5d12014-05-08 14:23:54 +0200473/* Show currently active_slave. */
Greg Kroah-Hartman43cb76d2002-04-09 12:14:34 -0700474static ssize_t bonding_show_active_slave(struct device *d,
475 struct device_attribute *attr,
476 char *buf)
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800477{
Greg Kroah-Hartman43cb76d2002-04-09 12:14:34 -0700478 struct bonding *bond = to_bond(d);
Jiri Pirko752d48b2013-10-18 17:43:37 +0200479 struct net_device *slave_dev;
Wagner Ferenc16cd0162007-12-06 23:40:29 -0800480 int count = 0;
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800481
nikolay@redhat.com278b2082013-08-01 16:54:51 +0200482 rcu_read_lock();
Jiri Pirko752d48b2013-10-18 17:43:37 +0200483 slave_dev = bond_option_active_slave_get_rcu(bond);
484 if (slave_dev)
485 count = sprintf(buf, "%s\n", slave_dev->name);
nikolay@redhat.com278b2082013-08-01 16:54:51 +0200486 rcu_read_unlock();
487
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800488 return count;
489}
Stephen Hemminger3d632c32009-06-12 19:02:48 +0000490static DEVICE_ATTR(active_slave, S_IRUGO | S_IWUSR,
Nikolay Aleksandrovdc3e5d12014-05-08 14:23:54 +0200491 bonding_show_active_slave, bonding_sysfs_store_option);
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800492
Nikolay Aleksandrovdc3e5d12014-05-08 14:23:54 +0200493/* Show link status of the bond interface. */
Greg Kroah-Hartman43cb76d2002-04-09 12:14:34 -0700494static ssize_t bonding_show_mii_status(struct device *d,
495 struct device_attribute *attr,
496 char *buf)
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800497{
Greg Kroah-Hartman43cb76d2002-04-09 12:14:34 -0700498 struct bonding *bond = to_bond(d);
Eric Dumazetc2646b52014-07-15 06:56:54 -0700499 bool active = !!rcu_access_pointer(bond->curr_active_slave);
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800500
Eric Dumazetc2646b52014-07-15 06:56:54 -0700501 return sprintf(buf, "%s\n", active ? "up" : "down");
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800502}
Greg Kroah-Hartman43cb76d2002-04-09 12:14:34 -0700503static DEVICE_ATTR(mii_status, S_IRUGO, bonding_show_mii_status, NULL);
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800504
Nikolay Aleksandrovdc3e5d12014-05-08 14:23:54 +0200505/* Show current 802.3ad aggregator ID. */
Greg Kroah-Hartman43cb76d2002-04-09 12:14:34 -0700506static ssize_t bonding_show_ad_aggregator(struct device *d,
507 struct device_attribute *attr,
508 char *buf)
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800509{
510 int count = 0;
Greg Kroah-Hartman43cb76d2002-04-09 12:14:34 -0700511 struct bonding *bond = to_bond(d);
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800512
Veaceslav Falico01844092014-05-15 21:39:55 +0200513 if (BOND_MODE(bond) == BOND_MODE_8023AD) {
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800514 struct ad_info ad_info;
Stephen Hemminger3d632c32009-06-12 19:02:48 +0000515 count = sprintf(buf, "%d\n",
nikolay@redhat.com318debd2013-05-18 01:18:31 +0000516 bond_3ad_get_active_agg_info(bond, &ad_info)
Stephen Hemminger3d632c32009-06-12 19:02:48 +0000517 ? 0 : ad_info.aggregator_id);
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800518 }
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800519
520 return count;
521}
Greg Kroah-Hartman43cb76d2002-04-09 12:14:34 -0700522static DEVICE_ATTR(ad_aggregator, S_IRUGO, bonding_show_ad_aggregator, NULL);
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800523
524
Nikolay Aleksandrovdc3e5d12014-05-08 14:23:54 +0200525/* Show number of active 802.3ad ports. */
Greg Kroah-Hartman43cb76d2002-04-09 12:14:34 -0700526static ssize_t bonding_show_ad_num_ports(struct device *d,
527 struct device_attribute *attr,
528 char *buf)
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800529{
530 int count = 0;
Greg Kroah-Hartman43cb76d2002-04-09 12:14:34 -0700531 struct bonding *bond = to_bond(d);
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800532
Veaceslav Falico01844092014-05-15 21:39:55 +0200533 if (BOND_MODE(bond) == BOND_MODE_8023AD) {
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800534 struct ad_info ad_info;
Stephen Hemminger3d632c32009-06-12 19:02:48 +0000535 count = sprintf(buf, "%d\n",
nikolay@redhat.com318debd2013-05-18 01:18:31 +0000536 bond_3ad_get_active_agg_info(bond, &ad_info)
Stephen Hemminger3d632c32009-06-12 19:02:48 +0000537 ? 0 : ad_info.ports);
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800538 }
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800539
540 return count;
541}
Greg Kroah-Hartman43cb76d2002-04-09 12:14:34 -0700542static DEVICE_ATTR(ad_num_ports, S_IRUGO, bonding_show_ad_num_ports, NULL);
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800543
544
Nikolay Aleksandrovdc3e5d12014-05-08 14:23:54 +0200545/* Show current 802.3ad actor key. */
Greg Kroah-Hartman43cb76d2002-04-09 12:14:34 -0700546static ssize_t bonding_show_ad_actor_key(struct device *d,
547 struct device_attribute *attr,
548 char *buf)
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800549{
550 int count = 0;
Greg Kroah-Hartman43cb76d2002-04-09 12:14:34 -0700551 struct bonding *bond = to_bond(d);
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800552
Veaceslav Falico01844092014-05-15 21:39:55 +0200553 if (BOND_MODE(bond) == BOND_MODE_8023AD) {
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800554 struct ad_info ad_info;
Stephen Hemminger3d632c32009-06-12 19:02:48 +0000555 count = sprintf(buf, "%d\n",
nikolay@redhat.com318debd2013-05-18 01:18:31 +0000556 bond_3ad_get_active_agg_info(bond, &ad_info)
Stephen Hemminger3d632c32009-06-12 19:02:48 +0000557 ? 0 : ad_info.actor_key);
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800558 }
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800559
560 return count;
561}
Greg Kroah-Hartman43cb76d2002-04-09 12:14:34 -0700562static DEVICE_ATTR(ad_actor_key, S_IRUGO, bonding_show_ad_actor_key, NULL);
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800563
564
Nikolay Aleksandrovdc3e5d12014-05-08 14:23:54 +0200565/* Show current 802.3ad partner key. */
Greg Kroah-Hartman43cb76d2002-04-09 12:14:34 -0700566static ssize_t bonding_show_ad_partner_key(struct device *d,
567 struct device_attribute *attr,
568 char *buf)
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800569{
570 int count = 0;
Greg Kroah-Hartman43cb76d2002-04-09 12:14:34 -0700571 struct bonding *bond = to_bond(d);
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800572
Veaceslav Falico01844092014-05-15 21:39:55 +0200573 if (BOND_MODE(bond) == BOND_MODE_8023AD) {
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800574 struct ad_info ad_info;
Stephen Hemminger3d632c32009-06-12 19:02:48 +0000575 count = sprintf(buf, "%d\n",
nikolay@redhat.com318debd2013-05-18 01:18:31 +0000576 bond_3ad_get_active_agg_info(bond, &ad_info)
Stephen Hemminger3d632c32009-06-12 19:02:48 +0000577 ? 0 : ad_info.partner_key);
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800578 }
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800579
580 return count;
581}
Greg Kroah-Hartman43cb76d2002-04-09 12:14:34 -0700582static DEVICE_ATTR(ad_partner_key, S_IRUGO, bonding_show_ad_partner_key, NULL);
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800583
584
Nikolay Aleksandrovdc3e5d12014-05-08 14:23:54 +0200585/* Show current 802.3ad partner mac. */
Greg Kroah-Hartman43cb76d2002-04-09 12:14:34 -0700586static ssize_t bonding_show_ad_partner_mac(struct device *d,
587 struct device_attribute *attr,
588 char *buf)
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800589{
590 int count = 0;
Greg Kroah-Hartman43cb76d2002-04-09 12:14:34 -0700591 struct bonding *bond = to_bond(d);
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800592
Veaceslav Falico01844092014-05-15 21:39:55 +0200593 if (BOND_MODE(bond) == BOND_MODE_8023AD) {
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800594 struct ad_info ad_info;
Stephen Hemminger3d632c32009-06-12 19:02:48 +0000595 if (!bond_3ad_get_active_agg_info(bond, &ad_info))
Johannes Berge1749612008-10-27 15:59:26 -0700596 count = sprintf(buf, "%pM\n", ad_info.partner_system);
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800597 }
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800598
599 return count;
600}
Greg Kroah-Hartman43cb76d2002-04-09 12:14:34 -0700601static DEVICE_ATTR(ad_partner_mac, S_IRUGO, bonding_show_ad_partner_mac, NULL);
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800602
Nikolay Aleksandrovdc3e5d12014-05-08 14:23:54 +0200603/* Show the queue_ids of the slaves in the current bond. */
Andy Gospodarekbb1d9122010-06-02 08:40:18 +0000604static ssize_t bonding_show_queue_id(struct device *d,
605 struct device_attribute *attr,
606 char *buf)
607{
Andy Gospodarekbb1d9122010-06-02 08:40:18 +0000608 struct bonding *bond = to_bond(d);
Veaceslav Falico9caff1e2013-09-25 09:20:14 +0200609 struct list_head *iter;
nikolay@redhat.comdec1e902013-08-01 16:54:47 +0200610 struct slave *slave;
611 int res = 0;
Andy Gospodarekbb1d9122010-06-02 08:40:18 +0000612
613 if (!rtnl_trylock())
614 return restart_syscall();
615
Veaceslav Falico9caff1e2013-09-25 09:20:14 +0200616 bond_for_each_slave(bond, slave, iter) {
Nicolas de Pesloüan79236682010-07-14 18:24:54 -0700617 if (res > (PAGE_SIZE - IFNAMSIZ - 6)) {
618 /* not enough space for another interface_name:queue_id pair */
Andy Gospodarekbb1d9122010-06-02 08:40:18 +0000619 if ((PAGE_SIZE - res) > 10)
620 res = PAGE_SIZE - 10;
621 res += sprintf(buf + res, "++more++ ");
622 break;
623 }
624 res += sprintf(buf + res, "%s:%d ",
625 slave->dev->name, slave->queue_id);
626 }
Andy Gospodarekbb1d9122010-06-02 08:40:18 +0000627 if (res)
628 buf[res-1] = '\n'; /* eat the leftover space */
dingtianhong4d1ae5f2013-10-15 16:28:42 +0800629
Andy Gospodarekbb1d9122010-06-02 08:40:18 +0000630 rtnl_unlock();
nikolay@redhat.comdec1e902013-08-01 16:54:47 +0200631
Andy Gospodarekbb1d9122010-06-02 08:40:18 +0000632 return res;
633}
Andy Gospodarekbb1d9122010-06-02 08:40:18 +0000634static DEVICE_ATTR(queue_id, S_IRUGO | S_IWUSR, bonding_show_queue_id,
Nikolay Aleksandrovdc3e5d12014-05-08 14:23:54 +0200635 bonding_sysfs_store_option);
Andy Gospodarekbb1d9122010-06-02 08:40:18 +0000636
637
Nikolay Aleksandrovdc3e5d12014-05-08 14:23:54 +0200638/* Show the all_slaves_active flag. */
Andy Gospodarekebd8e492010-06-02 08:39:21 +0000639static ssize_t bonding_show_slaves_active(struct device *d,
640 struct device_attribute *attr,
641 char *buf)
642{
643 struct bonding *bond = to_bond(d);
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800644
Andy Gospodarekebd8e492010-06-02 08:39:21 +0000645 return sprintf(buf, "%d\n", bond->params.all_slaves_active);
646}
Andy Gospodarekebd8e492010-06-02 08:39:21 +0000647static DEVICE_ATTR(all_slaves_active, S_IRUGO | S_IWUSR,
Nikolay Aleksandrovdc3e5d12014-05-08 14:23:54 +0200648 bonding_show_slaves_active, bonding_sysfs_store_option);
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800649
Nikolay Aleksandrovdc3e5d12014-05-08 14:23:54 +0200650/* Show the number of IGMP membership reports to send on link failure */
Flavio Leitnerc2952c32010-10-05 14:23:59 +0000651static ssize_t bonding_show_resend_igmp(struct device *d,
Flavio Leitner94265cf2011-05-25 08:38:58 +0000652 struct device_attribute *attr,
653 char *buf)
Flavio Leitnerc2952c32010-10-05 14:23:59 +0000654{
655 struct bonding *bond = to_bond(d);
656
657 return sprintf(buf, "%d\n", bond->params.resend_igmp);
658}
Flavio Leitnerc2952c32010-10-05 14:23:59 +0000659static DEVICE_ATTR(resend_igmp, S_IRUGO | S_IWUSR,
Nikolay Aleksandrovdc3e5d12014-05-08 14:23:54 +0200660 bonding_show_resend_igmp, bonding_sysfs_store_option);
Flavio Leitnerc2952c32010-10-05 14:23:59 +0000661
Neil Horman7eacd032013-09-13 11:05:33 -0400662
663static ssize_t bonding_show_lp_interval(struct device *d,
664 struct device_attribute *attr,
665 char *buf)
666{
667 struct bonding *bond = to_bond(d);
Nikolay Aleksandrovdc3e5d12014-05-08 14:23:54 +0200668
Neil Horman7eacd032013-09-13 11:05:33 -0400669 return sprintf(buf, "%d\n", bond->params.lp_interval);
670}
Neil Horman7eacd032013-09-13 11:05:33 -0400671static DEVICE_ATTR(lp_interval, S_IRUGO | S_IWUSR,
Nikolay Aleksandrovdc3e5d12014-05-08 14:23:54 +0200672 bonding_show_lp_interval, bonding_sysfs_store_option);
Neil Horman7eacd032013-09-13 11:05:33 -0400673
Mahesh Bandeware9f0fb82014-04-22 16:30:22 -0700674static ssize_t bonding_show_tlb_dynamic_lb(struct device *d,
675 struct device_attribute *attr,
676 char *buf)
677{
678 struct bonding *bond = to_bond(d);
679 return sprintf(buf, "%d\n", bond->params.tlb_dynamic_lb);
680}
Mahesh Bandeware9f0fb82014-04-22 16:30:22 -0700681static DEVICE_ATTR(tlb_dynamic_lb, S_IRUGO | S_IWUSR,
Nikolay Aleksandrovdc3e5d12014-05-08 14:23:54 +0200682 bonding_show_tlb_dynamic_lb, bonding_sysfs_store_option);
Mahesh Bandeware9f0fb82014-04-22 16:30:22 -0700683
Nikolay Aleksandrov73958322013-11-05 13:51:41 +0100684static ssize_t bonding_show_packets_per_slave(struct device *d,
685 struct device_attribute *attr,
686 char *buf)
687{
688 struct bonding *bond = to_bond(d);
Nikolay Aleksandrova752a8b2013-12-05 11:36:58 +0100689 unsigned int packets_per_slave = bond->params.packets_per_slave;
Nikolay Aleksandrovdc3e5d12014-05-08 14:23:54 +0200690
Nikolay Aleksandrova752a8b2013-12-05 11:36:58 +0100691 return sprintf(buf, "%u\n", packets_per_slave);
Nikolay Aleksandrov73958322013-11-05 13:51:41 +0100692}
Nikolay Aleksandrov73958322013-11-05 13:51:41 +0100693static DEVICE_ATTR(packets_per_slave, S_IRUGO | S_IWUSR,
Nikolay Aleksandrovdc3e5d12014-05-08 14:23:54 +0200694 bonding_show_packets_per_slave, bonding_sysfs_store_option);
Nikolay Aleksandrov73958322013-11-05 13:51:41 +0100695
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800696static struct attribute *per_bond_attrs[] = {
Greg Kroah-Hartman43cb76d2002-04-09 12:14:34 -0700697 &dev_attr_slaves.attr,
698 &dev_attr_mode.attr,
Jay Vosburghdd957c52007-10-09 19:57:24 -0700699 &dev_attr_fail_over_mac.attr,
Greg Kroah-Hartman43cb76d2002-04-09 12:14:34 -0700700 &dev_attr_arp_validate.attr,
Veaceslav Falico8599b522013-06-24 11:49:34 +0200701 &dev_attr_arp_all_targets.attr,
Greg Kroah-Hartman43cb76d2002-04-09 12:14:34 -0700702 &dev_attr_arp_interval.attr,
703 &dev_attr_arp_ip_target.attr,
704 &dev_attr_downdelay.attr,
705 &dev_attr_updelay.attr,
706 &dev_attr_lacp_rate.attr,
Jay Vosburghfd989c82008-11-04 17:51:16 -0800707 &dev_attr_ad_select.attr,
Greg Kroah-Hartman43cb76d2002-04-09 12:14:34 -0700708 &dev_attr_xmit_hash_policy.attr,
Ben Hutchingsad246c92011-04-26 15:25:52 +0000709 &dev_attr_num_grat_arp.attr,
710 &dev_attr_num_unsol_na.attr,
Greg Kroah-Hartman43cb76d2002-04-09 12:14:34 -0700711 &dev_attr_miimon.attr,
712 &dev_attr_primary.attr,
Jiri Pirkoa5499522009-09-25 03:28:09 +0000713 &dev_attr_primary_reselect.attr,
Greg Kroah-Hartman43cb76d2002-04-09 12:14:34 -0700714 &dev_attr_use_carrier.attr,
715 &dev_attr_active_slave.attr,
716 &dev_attr_mii_status.attr,
717 &dev_attr_ad_aggregator.attr,
718 &dev_attr_ad_num_ports.attr,
719 &dev_attr_ad_actor_key.attr,
720 &dev_attr_ad_partner_key.attr,
721 &dev_attr_ad_partner_mac.attr,
Andy Gospodarekbb1d9122010-06-02 08:40:18 +0000722 &dev_attr_queue_id.attr,
Andy Gospodarekebd8e492010-06-02 08:39:21 +0000723 &dev_attr_all_slaves_active.attr,
Flavio Leitnerc2952c32010-10-05 14:23:59 +0000724 &dev_attr_resend_igmp.attr,
stephen hemminger655f8912011-06-22 09:54:39 +0000725 &dev_attr_min_links.attr,
Neil Horman7eacd032013-09-13 11:05:33 -0400726 &dev_attr_lp_interval.attr,
Nikolay Aleksandrov73958322013-11-05 13:51:41 +0100727 &dev_attr_packets_per_slave.attr,
Mahesh Bandeware9f0fb82014-04-22 16:30:22 -0700728 &dev_attr_tlb_dynamic_lb.attr,
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800729 NULL,
730};
731
732static struct attribute_group bonding_group = {
733 .name = "bonding",
734 .attrs = per_bond_attrs,
735};
736
Nikolay Aleksandrovdc3e5d12014-05-08 14:23:54 +0200737/* Initialize sysfs. This sets up the bonding_masters file in
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800738 * /sys/class/net.
739 */
Eric W. Biederman4c224002011-10-12 21:56:25 +0000740int bond_create_sysfs(struct bond_net *bn)
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800741{
Jay Vosburghb8a97872008-06-13 18:12:04 -0700742 int ret;
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800743
Eric W. Biederman4c224002011-10-12 21:56:25 +0000744 bn->class_attr_bonding_masters = class_attr_bonding_masters;
Eric W. Biederman01718e32011-10-21 22:43:07 +0000745 sysfs_attr_init(&bn->class_attr_bonding_masters.attr);
Eric W. Biederman4c224002011-10-12 21:56:25 +0000746
Tejun Heo58292cbe2013-09-11 22:29:04 -0400747 ret = netdev_class_create_file_ns(&bn->class_attr_bonding_masters,
748 bn->net);
Nikolay Aleksandrovdc3e5d12014-05-08 14:23:54 +0200749 /* Permit multiple loads of the module by ignoring failures to
Jay Vosburgh877cbd32007-01-19 18:15:47 -0800750 * create the bonding_masters sysfs file. Bonding devices
751 * created by second or subsequent loads of the module will
752 * not be listed in, or controllable by, bonding_masters, but
753 * will have the usual "bonding" sysfs directory.
754 *
755 * This is done to preserve backwards compatibility for
756 * initscripts/sysconfig, which load bonding multiple times to
757 * configure multiple bonding devices.
758 */
759 if (ret == -EEXIST) {
Stephen Hemminger38d2f382008-05-14 22:35:04 -0700760 /* Is someone being kinky and naming a device bonding_master? */
Eric W. Biederman4c224002011-10-12 21:56:25 +0000761 if (__dev_get_by_name(bn->net,
Stephen Hemminger38d2f382008-05-14 22:35:04 -0700762 class_attr_bonding_masters.attr.name))
Joe Perches90194262014-02-15 16:01:45 -0800763 pr_err("network device named %s already exists in sysfs\n",
Stephen Hemminger38d2f382008-05-14 22:35:04 -0700764 class_attr_bonding_masters.attr.name);
Stephen Hemminger130aa612009-06-11 05:46:04 -0700765 ret = 0;
Jay Vosburgh877cbd32007-01-19 18:15:47 -0800766 }
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800767
768 return ret;
769
770}
771
Nikolay Aleksandrovdc3e5d12014-05-08 14:23:54 +0200772/* Remove /sys/class/net/bonding_masters. */
Eric W. Biederman4c224002011-10-12 21:56:25 +0000773void bond_destroy_sysfs(struct bond_net *bn)
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800774{
Tejun Heo58292cbe2013-09-11 22:29:04 -0400775 netdev_class_remove_file_ns(&bn->class_attr_bonding_masters, bn->net);
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800776}
777
Nikolay Aleksandrovdc3e5d12014-05-08 14:23:54 +0200778/* Initialize sysfs for each bond. This sets up and registers
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800779 * the 'bondctl' directory for each individual bond under /sys/class/net.
780 */
Eric W. Biederman6151b3d2009-10-29 14:18:22 +0000781void bond_prepare_sysfs_group(struct bonding *bond)
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800782{
Eric W. Biederman6151b3d2009-10-29 14:18:22 +0000783 bond->dev->sysfs_groups[0] = &bonding_group;
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800784}
785