blob: 98db8edd9c755c55d04a26b0b40143ba80d15a55 [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{
428 int count = 0;
Greg Kroah-Hartman43cb76d2002-04-09 12:14:34 -0700429 struct bonding *bond = to_bond(d);
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800430
431 if (bond->primary_slave)
Wagner Ferenc7bd46502007-12-06 23:40:28 -0800432 count = sprintf(buf, "%s\n", bond->primary_slave->dev->name);
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800433
434 return count;
435}
Stephen Hemminger3d632c32009-06-12 19:02:48 +0000436static DEVICE_ATTR(primary, S_IRUGO | S_IWUSR,
Nikolay Aleksandrovdc3e5d12014-05-08 14:23:54 +0200437 bonding_show_primary, bonding_sysfs_store_option);
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800438
Nikolay Aleksandrovdc3e5d12014-05-08 14:23:54 +0200439/* Show the primary_reselect flag. */
Jiri Pirkoa5499522009-09-25 03:28:09 +0000440static ssize_t bonding_show_primary_reselect(struct device *d,
441 struct device_attribute *attr,
442 char *buf)
443{
444 struct bonding *bond = to_bond(d);
stephen hemmingerf3253332014-03-04 16:36:44 -0800445 const struct bond_opt_value *val;
Nikolay Aleksandrov388d3a62014-01-22 14:53:33 +0100446
447 val = bond_opt_get_val(BOND_OPT_PRIMARY_RESELECT,
448 bond->params.primary_reselect);
Jiri Pirkoa5499522009-09-25 03:28:09 +0000449
450 return sprintf(buf, "%s %d\n",
Nikolay Aleksandrov388d3a62014-01-22 14:53:33 +0100451 val->string, bond->params.primary_reselect);
Jiri Pirkoa5499522009-09-25 03:28:09 +0000452}
Jiri Pirkoa5499522009-09-25 03:28:09 +0000453static DEVICE_ATTR(primary_reselect, S_IRUGO | S_IWUSR,
Nikolay Aleksandrovdc3e5d12014-05-08 14:23:54 +0200454 bonding_show_primary_reselect, bonding_sysfs_store_option);
Jiri Pirkoa5499522009-09-25 03:28:09 +0000455
Nikolay Aleksandrovdc3e5d12014-05-08 14:23:54 +0200456/* Show the use_carrier flag. */
Greg Kroah-Hartman43cb76d2002-04-09 12:14:34 -0700457static ssize_t bonding_show_carrier(struct device *d,
458 struct device_attribute *attr,
459 char *buf)
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800460{
Greg Kroah-Hartman43cb76d2002-04-09 12:14:34 -0700461 struct bonding *bond = to_bond(d);
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800462
Wagner Ferenc7bd46502007-12-06 23:40:28 -0800463 return sprintf(buf, "%d\n", bond->params.use_carrier);
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800464}
Stephen Hemminger3d632c32009-06-12 19:02:48 +0000465static DEVICE_ATTR(use_carrier, S_IRUGO | S_IWUSR,
Nikolay Aleksandrovdc3e5d12014-05-08 14:23:54 +0200466 bonding_show_carrier, bonding_sysfs_store_option);
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800467
468
Nikolay Aleksandrovdc3e5d12014-05-08 14:23:54 +0200469/* Show currently active_slave. */
Greg Kroah-Hartman43cb76d2002-04-09 12:14:34 -0700470static ssize_t bonding_show_active_slave(struct device *d,
471 struct device_attribute *attr,
472 char *buf)
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800473{
Greg Kroah-Hartman43cb76d2002-04-09 12:14:34 -0700474 struct bonding *bond = to_bond(d);
Jiri Pirko752d48b2013-10-18 17:43:37 +0200475 struct net_device *slave_dev;
Wagner Ferenc16cd0162007-12-06 23:40:29 -0800476 int count = 0;
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800477
nikolay@redhat.com278b2082013-08-01 16:54:51 +0200478 rcu_read_lock();
Jiri Pirko752d48b2013-10-18 17:43:37 +0200479 slave_dev = bond_option_active_slave_get_rcu(bond);
480 if (slave_dev)
481 count = sprintf(buf, "%s\n", slave_dev->name);
nikolay@redhat.com278b2082013-08-01 16:54:51 +0200482 rcu_read_unlock();
483
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800484 return count;
485}
Stephen Hemminger3d632c32009-06-12 19:02:48 +0000486static DEVICE_ATTR(active_slave, S_IRUGO | S_IWUSR,
Nikolay Aleksandrovdc3e5d12014-05-08 14:23:54 +0200487 bonding_show_active_slave, bonding_sysfs_store_option);
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800488
Nikolay Aleksandrovdc3e5d12014-05-08 14:23:54 +0200489/* Show link status of the bond interface. */
Greg Kroah-Hartman43cb76d2002-04-09 12:14:34 -0700490static ssize_t bonding_show_mii_status(struct device *d,
491 struct device_attribute *attr,
492 char *buf)
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800493{
Greg Kroah-Hartman43cb76d2002-04-09 12:14:34 -0700494 struct bonding *bond = to_bond(d);
Eric Dumazetc2646b52014-07-15 06:56:54 -0700495 bool active = !!rcu_access_pointer(bond->curr_active_slave);
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800496
Eric Dumazetc2646b52014-07-15 06:56:54 -0700497 return sprintf(buf, "%s\n", active ? "up" : "down");
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800498}
Greg Kroah-Hartman43cb76d2002-04-09 12:14:34 -0700499static DEVICE_ATTR(mii_status, S_IRUGO, bonding_show_mii_status, NULL);
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800500
Nikolay Aleksandrovdc3e5d12014-05-08 14:23:54 +0200501/* Show current 802.3ad aggregator ID. */
Greg Kroah-Hartman43cb76d2002-04-09 12:14:34 -0700502static ssize_t bonding_show_ad_aggregator(struct device *d,
503 struct device_attribute *attr,
504 char *buf)
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800505{
506 int count = 0;
Greg Kroah-Hartman43cb76d2002-04-09 12:14:34 -0700507 struct bonding *bond = to_bond(d);
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800508
Veaceslav Falico01844092014-05-15 21:39:55 +0200509 if (BOND_MODE(bond) == BOND_MODE_8023AD) {
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800510 struct ad_info ad_info;
Stephen Hemminger3d632c32009-06-12 19:02:48 +0000511 count = sprintf(buf, "%d\n",
nikolay@redhat.com318debd2013-05-18 01:18:31 +0000512 bond_3ad_get_active_agg_info(bond, &ad_info)
Stephen Hemminger3d632c32009-06-12 19:02:48 +0000513 ? 0 : ad_info.aggregator_id);
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800514 }
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800515
516 return count;
517}
Greg Kroah-Hartman43cb76d2002-04-09 12:14:34 -0700518static DEVICE_ATTR(ad_aggregator, S_IRUGO, bonding_show_ad_aggregator, NULL);
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800519
520
Nikolay Aleksandrovdc3e5d12014-05-08 14:23:54 +0200521/* Show number of active 802.3ad ports. */
Greg Kroah-Hartman43cb76d2002-04-09 12:14:34 -0700522static ssize_t bonding_show_ad_num_ports(struct device *d,
523 struct device_attribute *attr,
524 char *buf)
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800525{
526 int count = 0;
Greg Kroah-Hartman43cb76d2002-04-09 12:14:34 -0700527 struct bonding *bond = to_bond(d);
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800528
Veaceslav Falico01844092014-05-15 21:39:55 +0200529 if (BOND_MODE(bond) == BOND_MODE_8023AD) {
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800530 struct ad_info ad_info;
Stephen Hemminger3d632c32009-06-12 19:02:48 +0000531 count = sprintf(buf, "%d\n",
nikolay@redhat.com318debd2013-05-18 01:18:31 +0000532 bond_3ad_get_active_agg_info(bond, &ad_info)
Stephen Hemminger3d632c32009-06-12 19:02:48 +0000533 ? 0 : ad_info.ports);
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800534 }
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800535
536 return count;
537}
Greg Kroah-Hartman43cb76d2002-04-09 12:14:34 -0700538static DEVICE_ATTR(ad_num_ports, S_IRUGO, bonding_show_ad_num_ports, NULL);
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800539
540
Nikolay Aleksandrovdc3e5d12014-05-08 14:23:54 +0200541/* Show current 802.3ad actor key. */
Greg Kroah-Hartman43cb76d2002-04-09 12:14:34 -0700542static ssize_t bonding_show_ad_actor_key(struct device *d,
543 struct device_attribute *attr,
544 char *buf)
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800545{
546 int count = 0;
Greg Kroah-Hartman43cb76d2002-04-09 12:14:34 -0700547 struct bonding *bond = to_bond(d);
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800548
Veaceslav Falico01844092014-05-15 21:39:55 +0200549 if (BOND_MODE(bond) == BOND_MODE_8023AD) {
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800550 struct ad_info ad_info;
Stephen Hemminger3d632c32009-06-12 19:02:48 +0000551 count = sprintf(buf, "%d\n",
nikolay@redhat.com318debd2013-05-18 01:18:31 +0000552 bond_3ad_get_active_agg_info(bond, &ad_info)
Stephen Hemminger3d632c32009-06-12 19:02:48 +0000553 ? 0 : ad_info.actor_key);
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800554 }
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800555
556 return count;
557}
Greg Kroah-Hartman43cb76d2002-04-09 12:14:34 -0700558static DEVICE_ATTR(ad_actor_key, S_IRUGO, bonding_show_ad_actor_key, NULL);
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800559
560
Nikolay Aleksandrovdc3e5d12014-05-08 14:23:54 +0200561/* Show current 802.3ad partner key. */
Greg Kroah-Hartman43cb76d2002-04-09 12:14:34 -0700562static ssize_t bonding_show_ad_partner_key(struct device *d,
563 struct device_attribute *attr,
564 char *buf)
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800565{
566 int count = 0;
Greg Kroah-Hartman43cb76d2002-04-09 12:14:34 -0700567 struct bonding *bond = to_bond(d);
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800568
Veaceslav Falico01844092014-05-15 21:39:55 +0200569 if (BOND_MODE(bond) == BOND_MODE_8023AD) {
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800570 struct ad_info ad_info;
Stephen Hemminger3d632c32009-06-12 19:02:48 +0000571 count = sprintf(buf, "%d\n",
nikolay@redhat.com318debd2013-05-18 01:18:31 +0000572 bond_3ad_get_active_agg_info(bond, &ad_info)
Stephen Hemminger3d632c32009-06-12 19:02:48 +0000573 ? 0 : ad_info.partner_key);
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800574 }
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800575
576 return count;
577}
Greg Kroah-Hartman43cb76d2002-04-09 12:14:34 -0700578static DEVICE_ATTR(ad_partner_key, S_IRUGO, bonding_show_ad_partner_key, NULL);
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800579
580
Nikolay Aleksandrovdc3e5d12014-05-08 14:23:54 +0200581/* Show current 802.3ad partner mac. */
Greg Kroah-Hartman43cb76d2002-04-09 12:14:34 -0700582static ssize_t bonding_show_ad_partner_mac(struct device *d,
583 struct device_attribute *attr,
584 char *buf)
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800585{
586 int count = 0;
Greg Kroah-Hartman43cb76d2002-04-09 12:14:34 -0700587 struct bonding *bond = to_bond(d);
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800588
Veaceslav Falico01844092014-05-15 21:39:55 +0200589 if (BOND_MODE(bond) == BOND_MODE_8023AD) {
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800590 struct ad_info ad_info;
Stephen Hemminger3d632c32009-06-12 19:02:48 +0000591 if (!bond_3ad_get_active_agg_info(bond, &ad_info))
Johannes Berge1749612008-10-27 15:59:26 -0700592 count = sprintf(buf, "%pM\n", ad_info.partner_system);
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800593 }
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800594
595 return count;
596}
Greg Kroah-Hartman43cb76d2002-04-09 12:14:34 -0700597static DEVICE_ATTR(ad_partner_mac, S_IRUGO, bonding_show_ad_partner_mac, NULL);
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800598
Nikolay Aleksandrovdc3e5d12014-05-08 14:23:54 +0200599/* Show the queue_ids of the slaves in the current bond. */
Andy Gospodarekbb1d9122010-06-02 08:40:18 +0000600static ssize_t bonding_show_queue_id(struct device *d,
601 struct device_attribute *attr,
602 char *buf)
603{
Andy Gospodarekbb1d9122010-06-02 08:40:18 +0000604 struct bonding *bond = to_bond(d);
Veaceslav Falico9caff1e2013-09-25 09:20:14 +0200605 struct list_head *iter;
nikolay@redhat.comdec1e902013-08-01 16:54:47 +0200606 struct slave *slave;
607 int res = 0;
Andy Gospodarekbb1d9122010-06-02 08:40:18 +0000608
609 if (!rtnl_trylock())
610 return restart_syscall();
611
Veaceslav Falico9caff1e2013-09-25 09:20:14 +0200612 bond_for_each_slave(bond, slave, iter) {
Nicolas de Pesloüan79236682010-07-14 18:24:54 -0700613 if (res > (PAGE_SIZE - IFNAMSIZ - 6)) {
614 /* not enough space for another interface_name:queue_id pair */
Andy Gospodarekbb1d9122010-06-02 08:40:18 +0000615 if ((PAGE_SIZE - res) > 10)
616 res = PAGE_SIZE - 10;
617 res += sprintf(buf + res, "++more++ ");
618 break;
619 }
620 res += sprintf(buf + res, "%s:%d ",
621 slave->dev->name, slave->queue_id);
622 }
Andy Gospodarekbb1d9122010-06-02 08:40:18 +0000623 if (res)
624 buf[res-1] = '\n'; /* eat the leftover space */
dingtianhong4d1ae5f2013-10-15 16:28:42 +0800625
Andy Gospodarekbb1d9122010-06-02 08:40:18 +0000626 rtnl_unlock();
nikolay@redhat.comdec1e902013-08-01 16:54:47 +0200627
Andy Gospodarekbb1d9122010-06-02 08:40:18 +0000628 return res;
629}
Andy Gospodarekbb1d9122010-06-02 08:40:18 +0000630static DEVICE_ATTR(queue_id, S_IRUGO | S_IWUSR, bonding_show_queue_id,
Nikolay Aleksandrovdc3e5d12014-05-08 14:23:54 +0200631 bonding_sysfs_store_option);
Andy Gospodarekbb1d9122010-06-02 08:40:18 +0000632
633
Nikolay Aleksandrovdc3e5d12014-05-08 14:23:54 +0200634/* Show the all_slaves_active flag. */
Andy Gospodarekebd8e492010-06-02 08:39:21 +0000635static ssize_t bonding_show_slaves_active(struct device *d,
636 struct device_attribute *attr,
637 char *buf)
638{
639 struct bonding *bond = to_bond(d);
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800640
Andy Gospodarekebd8e492010-06-02 08:39:21 +0000641 return sprintf(buf, "%d\n", bond->params.all_slaves_active);
642}
Andy Gospodarekebd8e492010-06-02 08:39:21 +0000643static DEVICE_ATTR(all_slaves_active, S_IRUGO | S_IWUSR,
Nikolay Aleksandrovdc3e5d12014-05-08 14:23:54 +0200644 bonding_show_slaves_active, bonding_sysfs_store_option);
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800645
Nikolay Aleksandrovdc3e5d12014-05-08 14:23:54 +0200646/* Show the number of IGMP membership reports to send on link failure */
Flavio Leitnerc2952c32010-10-05 14:23:59 +0000647static ssize_t bonding_show_resend_igmp(struct device *d,
Flavio Leitner94265cf2011-05-25 08:38:58 +0000648 struct device_attribute *attr,
649 char *buf)
Flavio Leitnerc2952c32010-10-05 14:23:59 +0000650{
651 struct bonding *bond = to_bond(d);
652
653 return sprintf(buf, "%d\n", bond->params.resend_igmp);
654}
Flavio Leitnerc2952c32010-10-05 14:23:59 +0000655static DEVICE_ATTR(resend_igmp, S_IRUGO | S_IWUSR,
Nikolay Aleksandrovdc3e5d12014-05-08 14:23:54 +0200656 bonding_show_resend_igmp, bonding_sysfs_store_option);
Flavio Leitnerc2952c32010-10-05 14:23:59 +0000657
Neil Horman7eacd032013-09-13 11:05:33 -0400658
659static ssize_t bonding_show_lp_interval(struct device *d,
660 struct device_attribute *attr,
661 char *buf)
662{
663 struct bonding *bond = to_bond(d);
Nikolay Aleksandrovdc3e5d12014-05-08 14:23:54 +0200664
Neil Horman7eacd032013-09-13 11:05:33 -0400665 return sprintf(buf, "%d\n", bond->params.lp_interval);
666}
Neil Horman7eacd032013-09-13 11:05:33 -0400667static DEVICE_ATTR(lp_interval, S_IRUGO | S_IWUSR,
Nikolay Aleksandrovdc3e5d12014-05-08 14:23:54 +0200668 bonding_show_lp_interval, bonding_sysfs_store_option);
Neil Horman7eacd032013-09-13 11:05:33 -0400669
Mahesh Bandeware9f0fb82014-04-22 16:30:22 -0700670static ssize_t bonding_show_tlb_dynamic_lb(struct device *d,
671 struct device_attribute *attr,
672 char *buf)
673{
674 struct bonding *bond = to_bond(d);
675 return sprintf(buf, "%d\n", bond->params.tlb_dynamic_lb);
676}
Mahesh Bandeware9f0fb82014-04-22 16:30:22 -0700677static DEVICE_ATTR(tlb_dynamic_lb, S_IRUGO | S_IWUSR,
Nikolay Aleksandrovdc3e5d12014-05-08 14:23:54 +0200678 bonding_show_tlb_dynamic_lb, bonding_sysfs_store_option);
Mahesh Bandeware9f0fb82014-04-22 16:30:22 -0700679
Nikolay Aleksandrov73958322013-11-05 13:51:41 +0100680static ssize_t bonding_show_packets_per_slave(struct device *d,
681 struct device_attribute *attr,
682 char *buf)
683{
684 struct bonding *bond = to_bond(d);
Nikolay Aleksandrova752a8b2013-12-05 11:36:58 +0100685 unsigned int packets_per_slave = bond->params.packets_per_slave;
Nikolay Aleksandrovdc3e5d12014-05-08 14:23:54 +0200686
Nikolay Aleksandrova752a8b2013-12-05 11:36:58 +0100687 return sprintf(buf, "%u\n", packets_per_slave);
Nikolay Aleksandrov73958322013-11-05 13:51:41 +0100688}
Nikolay Aleksandrov73958322013-11-05 13:51:41 +0100689static DEVICE_ATTR(packets_per_slave, S_IRUGO | S_IWUSR,
Nikolay Aleksandrovdc3e5d12014-05-08 14:23:54 +0200690 bonding_show_packets_per_slave, bonding_sysfs_store_option);
Nikolay Aleksandrov73958322013-11-05 13:51:41 +0100691
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800692static struct attribute *per_bond_attrs[] = {
Greg Kroah-Hartman43cb76d2002-04-09 12:14:34 -0700693 &dev_attr_slaves.attr,
694 &dev_attr_mode.attr,
Jay Vosburghdd957c52007-10-09 19:57:24 -0700695 &dev_attr_fail_over_mac.attr,
Greg Kroah-Hartman43cb76d2002-04-09 12:14:34 -0700696 &dev_attr_arp_validate.attr,
Veaceslav Falico8599b522013-06-24 11:49:34 +0200697 &dev_attr_arp_all_targets.attr,
Greg Kroah-Hartman43cb76d2002-04-09 12:14:34 -0700698 &dev_attr_arp_interval.attr,
699 &dev_attr_arp_ip_target.attr,
700 &dev_attr_downdelay.attr,
701 &dev_attr_updelay.attr,
702 &dev_attr_lacp_rate.attr,
Jay Vosburghfd989c82008-11-04 17:51:16 -0800703 &dev_attr_ad_select.attr,
Greg Kroah-Hartman43cb76d2002-04-09 12:14:34 -0700704 &dev_attr_xmit_hash_policy.attr,
Ben Hutchingsad246c92011-04-26 15:25:52 +0000705 &dev_attr_num_grat_arp.attr,
706 &dev_attr_num_unsol_na.attr,
Greg Kroah-Hartman43cb76d2002-04-09 12:14:34 -0700707 &dev_attr_miimon.attr,
708 &dev_attr_primary.attr,
Jiri Pirkoa5499522009-09-25 03:28:09 +0000709 &dev_attr_primary_reselect.attr,
Greg Kroah-Hartman43cb76d2002-04-09 12:14:34 -0700710 &dev_attr_use_carrier.attr,
711 &dev_attr_active_slave.attr,
712 &dev_attr_mii_status.attr,
713 &dev_attr_ad_aggregator.attr,
714 &dev_attr_ad_num_ports.attr,
715 &dev_attr_ad_actor_key.attr,
716 &dev_attr_ad_partner_key.attr,
717 &dev_attr_ad_partner_mac.attr,
Andy Gospodarekbb1d9122010-06-02 08:40:18 +0000718 &dev_attr_queue_id.attr,
Andy Gospodarekebd8e492010-06-02 08:39:21 +0000719 &dev_attr_all_slaves_active.attr,
Flavio Leitnerc2952c32010-10-05 14:23:59 +0000720 &dev_attr_resend_igmp.attr,
stephen hemminger655f8912011-06-22 09:54:39 +0000721 &dev_attr_min_links.attr,
Neil Horman7eacd032013-09-13 11:05:33 -0400722 &dev_attr_lp_interval.attr,
Nikolay Aleksandrov73958322013-11-05 13:51:41 +0100723 &dev_attr_packets_per_slave.attr,
Mahesh Bandeware9f0fb82014-04-22 16:30:22 -0700724 &dev_attr_tlb_dynamic_lb.attr,
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800725 NULL,
726};
727
728static struct attribute_group bonding_group = {
729 .name = "bonding",
730 .attrs = per_bond_attrs,
731};
732
Nikolay Aleksandrovdc3e5d12014-05-08 14:23:54 +0200733/* Initialize sysfs. This sets up the bonding_masters file in
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800734 * /sys/class/net.
735 */
Eric W. Biederman4c224002011-10-12 21:56:25 +0000736int bond_create_sysfs(struct bond_net *bn)
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800737{
Jay Vosburghb8a97872008-06-13 18:12:04 -0700738 int ret;
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800739
Eric W. Biederman4c224002011-10-12 21:56:25 +0000740 bn->class_attr_bonding_masters = class_attr_bonding_masters;
Eric W. Biederman01718e32011-10-21 22:43:07 +0000741 sysfs_attr_init(&bn->class_attr_bonding_masters.attr);
Eric W. Biederman4c224002011-10-12 21:56:25 +0000742
Tejun Heo58292cbe2013-09-11 22:29:04 -0400743 ret = netdev_class_create_file_ns(&bn->class_attr_bonding_masters,
744 bn->net);
Nikolay Aleksandrovdc3e5d12014-05-08 14:23:54 +0200745 /* Permit multiple loads of the module by ignoring failures to
Jay Vosburgh877cbd32007-01-19 18:15:47 -0800746 * create the bonding_masters sysfs file. Bonding devices
747 * created by second or subsequent loads of the module will
748 * not be listed in, or controllable by, bonding_masters, but
749 * will have the usual "bonding" sysfs directory.
750 *
751 * This is done to preserve backwards compatibility for
752 * initscripts/sysconfig, which load bonding multiple times to
753 * configure multiple bonding devices.
754 */
755 if (ret == -EEXIST) {
Stephen Hemminger38d2f382008-05-14 22:35:04 -0700756 /* Is someone being kinky and naming a device bonding_master? */
Eric W. Biederman4c224002011-10-12 21:56:25 +0000757 if (__dev_get_by_name(bn->net,
Stephen Hemminger38d2f382008-05-14 22:35:04 -0700758 class_attr_bonding_masters.attr.name))
Joe Perches90194262014-02-15 16:01:45 -0800759 pr_err("network device named %s already exists in sysfs\n",
Stephen Hemminger38d2f382008-05-14 22:35:04 -0700760 class_attr_bonding_masters.attr.name);
Stephen Hemminger130aa612009-06-11 05:46:04 -0700761 ret = 0;
Jay Vosburgh877cbd32007-01-19 18:15:47 -0800762 }
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800763
764 return ret;
765
766}
767
Nikolay Aleksandrovdc3e5d12014-05-08 14:23:54 +0200768/* Remove /sys/class/net/bonding_masters. */
Eric W. Biederman4c224002011-10-12 21:56:25 +0000769void bond_destroy_sysfs(struct bond_net *bn)
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800770{
Tejun Heo58292cbe2013-09-11 22:29:04 -0400771 netdev_class_remove_file_ns(&bn->class_attr_bonding_masters, bn->net);
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800772}
773
Nikolay Aleksandrovdc3e5d12014-05-08 14:23:54 +0200774/* Initialize sysfs for each bond. This sets up and registers
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800775 * the 'bondctl' directory for each individual bond under /sys/class/net.
776 */
Eric W. Biederman6151b3d2009-10-29 14:18:22 +0000777void bond_prepare_sysfs_group(struct bonding *bond)
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800778{
Eric W. Biederman6151b3d2009-10-29 14:18:22 +0000779 bond->dev->sysfs_groups[0] = &bonding_group;
Mitch Williamsb76cdba2005-11-09 10:36:41 -0800780}
781