]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blame - drivers/net/bonding/bond_sysfs.c
bonding: get rid of bond_option_active_slave_get()
[mirror_ubuntu-artful-kernel.git] / drivers / net / bonding / bond_sysfs.c
CommitLineData
b76cdba9
MW
1/*
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
adf8d3ff 15 * with this program; if not, see <http://www.gnu.org/licenses/>.
b76cdba9
MW
16 *
17 * The full GNU General Public License is included in this distribution in the
18 * file called LICENSE.
19 *
b76cdba9 20 */
a4aee5c8
JP
21
22#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
23
b76cdba9
MW
24#include <linux/kernel.h>
25#include <linux/module.h>
b76cdba9 26#include <linux/device.h>
d43c36dc 27#include <linux/sched.h>
b76cdba9
MW
28#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>
b76cdba9
MW
35#include <linux/ctype.h>
36#include <linux/inet.h>
37#include <linux/rtnetlink.h>
5c5129b5 38#include <linux/etherdevice.h>
881d966b 39#include <net/net_namespace.h>
ec87fd3b
EB
40#include <net/netns/generic.h>
41#include <linux/nsproxy.h>
b76cdba9 42
b76cdba9 43#include "bonding.h"
5a03cdb7 44
3d632c3f 45#define to_dev(obj) container_of(obj, struct device, kobj)
454d7c9b 46#define to_bond(cd) ((struct bonding *)(netdev_priv(to_net_dev(cd))))
b76cdba9 47
dc3e5d18 48/* "show" function for the bond_masters attribute.
b76cdba9
MW
49 * The class parameter is ignored.
50 */
28812fe1
AK
51static ssize_t bonding_show_bonds(struct class *cls,
52 struct class_attribute *attr,
53 char *buf)
b76cdba9 54{
4c22400a
EB
55 struct bond_net *bn =
56 container_of(attr, struct bond_net, class_attr_bonding_masters);
b76cdba9
MW
57 int res = 0;
58 struct bonding *bond;
59
7e083840 60 rtnl_lock();
b76cdba9 61
ec87fd3b 62 list_for_each_entry(bond, &bn->dev_list, bond_list) {
b76cdba9
MW
63 if (res > (PAGE_SIZE - IFNAMSIZ)) {
64 /* not enough space for another interface name */
65 if ((PAGE_SIZE - res) > 10)
66 res = PAGE_SIZE - 10;
b8843665 67 res += sprintf(buf + res, "++more++ ");
b76cdba9
MW
68 break;
69 }
b8843665 70 res += sprintf(buf + res, "%s ", bond->dev->name);
b76cdba9 71 }
1dcdcd69
WF
72 if (res)
73 buf[res-1] = '\n'; /* eat the leftover space */
7e083840
SH
74
75 rtnl_unlock();
b76cdba9
MW
76 return res;
77}
78
4c22400a 79static struct net_device *bond_get_by_name(struct bond_net *bn, const char *ifname)
373500db
SH
80{
81 struct bonding *bond;
82
ec87fd3b 83 list_for_each_entry(bond, &bn->dev_list, bond_list) {
373500db
SH
84 if (strncmp(bond->dev->name, ifname, IFNAMSIZ) == 0)
85 return bond->dev;
86 }
87 return NULL;
88}
89
dc3e5d18 90/* "store" function for the bond_masters attribute. This is what
b76cdba9
MW
91 * creates and deletes entire bonds.
92 *
93 * The class parameter is ignored.
94 *
95 */
3d632c3f 96static ssize_t bonding_store_bonds(struct class *cls,
28812fe1 97 struct class_attribute *attr,
3d632c3f 98 const char *buffer, size_t count)
b76cdba9 99{
4c22400a
EB
100 struct bond_net *bn =
101 container_of(attr, struct bond_net, class_attr_bonding_masters);
b76cdba9
MW
102 char command[IFNAMSIZ + 1] = {0, };
103 char *ifname;
027ea041 104 int rv, res = count;
b76cdba9 105
b76cdba9
MW
106 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] == '+') {
a4aee5c8 113 pr_info("%s is being created...\n", ifname);
4c22400a 114 rv = bond_create(bn->net, ifname);
027ea041 115 if (rv) {
5f86cad1 116 if (rv == -EEXIST)
90194264 117 pr_info("%s already exists\n", ifname);
5f86cad1 118 else
90194264 119 pr_info("%s creation failed\n", ifname);
027ea041 120 res = rv;
b76cdba9 121 }
373500db
SH
122 } else if (command[0] == '-') {
123 struct net_device *bond_dev;
b76cdba9 124
027ea041 125 rtnl_lock();
4c22400a 126 bond_dev = bond_get_by_name(bn, ifname);
373500db 127 if (bond_dev) {
a4aee5c8 128 pr_info("%s is being deleted...\n", ifname);
373500db
SH
129 unregister_netdevice(bond_dev);
130 } else {
a4aee5c8 131 pr_err("unable to delete non-existent %s\n", ifname);
373500db
SH
132 res = -ENODEV;
133 }
134 rtnl_unlock();
135 } else
136 goto err_no_cmd;
027ea041 137
373500db
SH
138 /* Always return either count or an error. If you return 0, you'll
139 * get called forever, which is bad.
140 */
141 return res;
b76cdba9
MW
142
143err_no_cmd:
90194264 144 pr_err("no command found in bonding_masters - use +ifname or -ifname\n");
c4ebc66a 145 return -EPERM;
b76cdba9 146}
373500db 147
b76cdba9 148/* class attribute for bond_masters file. This ends up in /sys/class/net */
4c22400a
EB
149static 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,
4c22400a 156};
b76cdba9 157
dc3e5d18
NA
158/* 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. */
43cb76d9
GKH
178static ssize_t bonding_show_slaves(struct device *d,
179 struct device_attribute *attr, char *buf)
b76cdba9 180{
43cb76d9 181 struct bonding *bond = to_bond(d);
9caff1e7 182 struct list_head *iter;
dec1e90e 183 struct slave *slave;
184 int res = 0;
b76cdba9 185
4d1ae5fb 186 if (!rtnl_trylock())
187 return restart_syscall();
188
9caff1e7 189 bond_for_each_slave(bond, slave, iter) {
b76cdba9
MW
190 if (res > (PAGE_SIZE - IFNAMSIZ)) {
191 /* not enough space for another interface name */
192 if ((PAGE_SIZE - res) > 10)
193 res = PAGE_SIZE - 10;
7bd46508 194 res += sprintf(buf + res, "++more++ ");
b76cdba9
MW
195 break;
196 }
197 res += sprintf(buf + res, "%s ", slave->dev->name);
198 }
4d1ae5fb 199
200 rtnl_unlock();
201
1dcdcd69
WF
202 if (res)
203 buf[res-1] = '\n'; /* eat the leftover space */
dec1e90e 204
b76cdba9
MW
205 return res;
206}
3d632c3f 207static DEVICE_ATTR(slaves, S_IRUGO | S_IWUSR, bonding_show_slaves,
dc3e5d18 208 bonding_sysfs_store_option);
b76cdba9 209
dc3e5d18 210/* Show the bonding mode. */
43cb76d9
GKH
211static ssize_t bonding_show_mode(struct device *d,
212 struct device_attribute *attr, char *buf)
b76cdba9 213{
43cb76d9 214 struct bonding *bond = to_bond(d);
f3253339 215 const struct bond_opt_value *val;
b76cdba9 216
01844098 217 val = bond_opt_get_val(BOND_OPT_MODE, BOND_MODE(bond));
2b3798d5 218
01844098 219 return sprintf(buf, "%s %d\n", val->string, BOND_MODE(bond));
b76cdba9 220}
3d632c3f 221static DEVICE_ATTR(mode, S_IRUGO | S_IWUSR,
dc3e5d18 222 bonding_show_mode, bonding_sysfs_store_option);
b76cdba9 223
dc3e5d18 224/* Show the bonding transmit hash method. */
43cb76d9
GKH
225static ssize_t bonding_show_xmit_hash(struct device *d,
226 struct device_attribute *attr,
227 char *buf)
b76cdba9 228{
43cb76d9 229 struct bonding *bond = to_bond(d);
f3253339 230 const struct bond_opt_value *val;
a4b32ce7
NA
231
232 val = bond_opt_get_val(BOND_OPT_XMIT_HASH, bond->params.xmit_policy);
b76cdba9 233
a4b32ce7 234 return sprintf(buf, "%s %d\n", val->string, bond->params.xmit_policy);
b76cdba9 235}
3d632c3f 236static DEVICE_ATTR(xmit_hash_policy, S_IRUGO | S_IWUSR,
dc3e5d18 237 bonding_show_xmit_hash, bonding_sysfs_store_option);
b76cdba9 238
dc3e5d18 239/* Show arp_validate. */
43cb76d9
GKH
240static ssize_t bonding_show_arp_validate(struct device *d,
241 struct device_attribute *attr,
242 char *buf)
f5b2b966 243{
43cb76d9 244 struct bonding *bond = to_bond(d);
f3253339 245 const struct bond_opt_value *val;
16228881
NA
246
247 val = bond_opt_get_val(BOND_OPT_ARP_VALIDATE,
248 bond->params.arp_validate);
f5b2b966 249
16228881 250 return sprintf(buf, "%s %d\n", val->string, bond->params.arp_validate);
f5b2b966 251}
3d632c3f 252static DEVICE_ATTR(arp_validate, S_IRUGO | S_IWUSR, bonding_show_arp_validate,
dc3e5d18
NA
253 bonding_sysfs_store_option);
254
255/* Show arp_all_targets. */
8599b52e
VF
256static 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);
f3253339 261 const struct bond_opt_value *val;
8599b52e 262
edf36b24
NA
263 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);
8599b52e 267}
8599b52e 268static DEVICE_ATTR(arp_all_targets, S_IRUGO | S_IWUSR,
dc3e5d18 269 bonding_show_arp_all_targets, bonding_sysfs_store_option);
f5b2b966 270
dc3e5d18 271/* Show fail_over_mac. */
3d632c3f
SH
272static ssize_t bonding_show_fail_over_mac(struct device *d,
273 struct device_attribute *attr,
274 char *buf)
dd957c57
JV
275{
276 struct bonding *bond = to_bond(d);
f3253339 277 const struct bond_opt_value *val;
dd957c57 278
1df6b6aa
NA
279 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);
dd957c57 283}
3d632c3f 284static DEVICE_ATTR(fail_over_mac, S_IRUGO | S_IWUSR,
dc3e5d18 285 bonding_show_fail_over_mac, bonding_sysfs_store_option);
dd957c57 286
dc3e5d18 287/* Show the arp timer interval. */
43cb76d9
GKH
288static ssize_t bonding_show_arp_interval(struct device *d,
289 struct device_attribute *attr,
290 char *buf)
b76cdba9 291{
43cb76d9 292 struct bonding *bond = to_bond(d);
b76cdba9 293
7bd46508 294 return sprintf(buf, "%d\n", bond->params.arp_interval);
b76cdba9 295}
3d632c3f 296static DEVICE_ATTR(arp_interval, S_IRUGO | S_IWUSR,
dc3e5d18 297 bonding_show_arp_interval, bonding_sysfs_store_option);
b76cdba9 298
dc3e5d18 299/* Show the arp targets. */
43cb76d9
GKH
300static ssize_t bonding_show_arp_targets(struct device *d,
301 struct device_attribute *attr,
302 char *buf)
b76cdba9 303{
43cb76d9 304 struct bonding *bond = to_bond(d);
4fb0ef58 305 int i, res = 0;
b76cdba9
MW
306
307 for (i = 0; i < BOND_MAX_ARP_TARGETS; i++) {
308 if (bond->params.arp_targets[i])
63779436
HH
309 res += sprintf(buf + res, "%pI4 ",
310 &bond->params.arp_targets[i]);
b76cdba9 311 }
1dcdcd69
WF
312 if (res)
313 buf[res-1] = '\n'; /* eat the leftover space */
4fb0ef58 314
b76cdba9
MW
315 return res;
316}
dc3e5d18
NA
317static DEVICE_ATTR(arp_ip_target, S_IRUGO | S_IWUSR,
318 bonding_show_arp_targets, bonding_sysfs_store_option);
b76cdba9 319
dc3e5d18 320/* Show the up and down delays. */
43cb76d9
GKH
321static ssize_t bonding_show_downdelay(struct device *d,
322 struct device_attribute *attr,
323 char *buf)
b76cdba9 324{
43cb76d9 325 struct bonding *bond = to_bond(d);
b76cdba9 326
7bd46508 327 return sprintf(buf, "%d\n", bond->params.downdelay * bond->params.miimon);
b76cdba9 328}
3d632c3f 329static DEVICE_ATTR(downdelay, S_IRUGO | S_IWUSR,
dc3e5d18 330 bonding_show_downdelay, bonding_sysfs_store_option);
b76cdba9 331
43cb76d9
GKH
332static ssize_t bonding_show_updelay(struct device *d,
333 struct device_attribute *attr,
334 char *buf)
b76cdba9 335{
43cb76d9 336 struct bonding *bond = to_bond(d);
b76cdba9 337
7bd46508 338 return sprintf(buf, "%d\n", bond->params.updelay * bond->params.miimon);
b76cdba9
MW
339
340}
3d632c3f 341static DEVICE_ATTR(updelay, S_IRUGO | S_IWUSR,
dc3e5d18 342 bonding_show_updelay, bonding_sysfs_store_option);
b76cdba9 343
dc3e5d18 344/* Show the LACP interval. */
43cb76d9
GKH
345static ssize_t bonding_show_lacp(struct device *d,
346 struct device_attribute *attr,
347 char *buf)
b76cdba9 348{
43cb76d9 349 struct bonding *bond = to_bond(d);
f3253339 350 const struct bond_opt_value *val;
b76cdba9 351
d3131de7
NA
352 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);
b76cdba9 355}
3d632c3f 356static DEVICE_ATTR(lacp_rate, S_IRUGO | S_IWUSR,
dc3e5d18 357 bonding_show_lacp, bonding_sysfs_store_option);
b76cdba9 358
655f8919 359static 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
014f1b20 365 return sprintf(buf, "%u\n", bond->params.min_links);
655f8919 366}
655f8919 367static DEVICE_ATTR(min_links, S_IRUGO | S_IWUSR,
dc3e5d18 368 bonding_show_min_links, bonding_sysfs_store_option);
655f8919 369
fd989c83
JV
370static 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);
f3253339 375 const struct bond_opt_value *val;
fd989c83 376
9e5f5eeb
NA
377 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);
fd989c83 380}
3d632c3f 381static DEVICE_ATTR(ad_select, S_IRUGO | S_IWUSR,
dc3e5d18 382 bonding_show_ad_select, bonding_sysfs_store_option);
fd989c83 383
dc3e5d18 384/* Show and set the number of peer notifications to send after a failover event. */
ad246c99
BH
385static 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);
2c9839c1 398 int ret;
399
ef56becb 400 ret = bond_opt_tryset_rtnl(bond, BOND_OPT_NUM_PEER_NOTIF, (char *)buf);
2c9839c1 401 if (!ret)
402 ret = count;
403
2c9839c1 404 return ret;
ad246c99
BH
405}
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
dc3e5d18 411/* Show the MII monitor interval. */
43cb76d9
GKH
412static ssize_t bonding_show_miimon(struct device *d,
413 struct device_attribute *attr,
414 char *buf)
b76cdba9 415{
43cb76d9 416 struct bonding *bond = to_bond(d);
b76cdba9 417
7bd46508 418 return sprintf(buf, "%d\n", bond->params.miimon);
b76cdba9 419}
3d632c3f 420static DEVICE_ATTR(miimon, S_IRUGO | S_IWUSR,
dc3e5d18 421 bonding_show_miimon, bonding_sysfs_store_option);
b76cdba9 422
dc3e5d18 423/* Show the primary slave. */
43cb76d9
GKH
424static ssize_t bonding_show_primary(struct device *d,
425 struct device_attribute *attr,
426 char *buf)
b76cdba9
MW
427{
428 int count = 0;
43cb76d9 429 struct bonding *bond = to_bond(d);
b76cdba9
MW
430
431 if (bond->primary_slave)
7bd46508 432 count = sprintf(buf, "%s\n", bond->primary_slave->dev->name);
b76cdba9
MW
433
434 return count;
435}
3d632c3f 436static DEVICE_ATTR(primary, S_IRUGO | S_IWUSR,
dc3e5d18 437 bonding_show_primary, bonding_sysfs_store_option);
b76cdba9 438
dc3e5d18 439/* Show the primary_reselect flag. */
a549952a
JP
440static 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);
f3253339 445 const struct bond_opt_value *val;
388d3a6d
NA
446
447 val = bond_opt_get_val(BOND_OPT_PRIMARY_RESELECT,
448 bond->params.primary_reselect);
a549952a
JP
449
450 return sprintf(buf, "%s %d\n",
388d3a6d 451 val->string, bond->params.primary_reselect);
a549952a 452}
a549952a 453static DEVICE_ATTR(primary_reselect, S_IRUGO | S_IWUSR,
dc3e5d18 454 bonding_show_primary_reselect, bonding_sysfs_store_option);
a549952a 455
dc3e5d18 456/* Show the use_carrier flag. */
43cb76d9
GKH
457static ssize_t bonding_show_carrier(struct device *d,
458 struct device_attribute *attr,
459 char *buf)
b76cdba9 460{
43cb76d9 461 struct bonding *bond = to_bond(d);
b76cdba9 462
7bd46508 463 return sprintf(buf, "%d\n", bond->params.use_carrier);
b76cdba9 464}
3d632c3f 465static DEVICE_ATTR(use_carrier, S_IRUGO | S_IWUSR,
dc3e5d18 466 bonding_show_carrier, bonding_sysfs_store_option);
b76cdba9
MW
467
468
dc3e5d18 469/* Show currently active_slave. */
43cb76d9
GKH
470static ssize_t bonding_show_active_slave(struct device *d,
471 struct device_attribute *attr,
472 char *buf)
b76cdba9 473{
43cb76d9 474 struct bonding *bond = to_bond(d);
752d48b5 475 struct net_device *slave_dev;
16cd0160 476 int count = 0;
b76cdba9 477
278b2083 478 rcu_read_lock();
752d48b5
JP
479 slave_dev = bond_option_active_slave_get_rcu(bond);
480 if (slave_dev)
481 count = sprintf(buf, "%s\n", slave_dev->name);
278b2083 482 rcu_read_unlock();
483
b76cdba9
MW
484 return count;
485}
3d632c3f 486static DEVICE_ATTR(active_slave, S_IRUGO | S_IWUSR,
dc3e5d18 487 bonding_show_active_slave, bonding_sysfs_store_option);
b76cdba9 488
dc3e5d18 489/* Show link status of the bond interface. */
43cb76d9
GKH
490static ssize_t bonding_show_mii_status(struct device *d,
491 struct device_attribute *attr,
492 char *buf)
b76cdba9 493{
43cb76d9 494 struct bonding *bond = to_bond(d);
b76cdba9 495
278b2083 496 return sprintf(buf, "%s\n", bond->curr_active_slave ? "up" : "down");
b76cdba9 497}
43cb76d9 498static DEVICE_ATTR(mii_status, S_IRUGO, bonding_show_mii_status, NULL);
b76cdba9 499
dc3e5d18 500/* Show current 802.3ad aggregator ID. */
43cb76d9
GKH
501static ssize_t bonding_show_ad_aggregator(struct device *d,
502 struct device_attribute *attr,
503 char *buf)
b76cdba9
MW
504{
505 int count = 0;
43cb76d9 506 struct bonding *bond = to_bond(d);
b76cdba9 507
01844098 508 if (BOND_MODE(bond) == BOND_MODE_8023AD) {
b76cdba9 509 struct ad_info ad_info;
3d632c3f 510 count = sprintf(buf, "%d\n",
318debd8 511 bond_3ad_get_active_agg_info(bond, &ad_info)
3d632c3f 512 ? 0 : ad_info.aggregator_id);
b76cdba9 513 }
b76cdba9
MW
514
515 return count;
516}
43cb76d9 517static DEVICE_ATTR(ad_aggregator, S_IRUGO, bonding_show_ad_aggregator, NULL);
b76cdba9
MW
518
519
dc3e5d18 520/* Show number of active 802.3ad ports. */
43cb76d9
GKH
521static ssize_t bonding_show_ad_num_ports(struct device *d,
522 struct device_attribute *attr,
523 char *buf)
b76cdba9
MW
524{
525 int count = 0;
43cb76d9 526 struct bonding *bond = to_bond(d);
b76cdba9 527
01844098 528 if (BOND_MODE(bond) == BOND_MODE_8023AD) {
b76cdba9 529 struct ad_info ad_info;
3d632c3f 530 count = sprintf(buf, "%d\n",
318debd8 531 bond_3ad_get_active_agg_info(bond, &ad_info)
3d632c3f 532 ? 0 : ad_info.ports);
b76cdba9 533 }
b76cdba9
MW
534
535 return count;
536}
43cb76d9 537static DEVICE_ATTR(ad_num_ports, S_IRUGO, bonding_show_ad_num_ports, NULL);
b76cdba9
MW
538
539
dc3e5d18 540/* Show current 802.3ad actor key. */
43cb76d9
GKH
541static ssize_t bonding_show_ad_actor_key(struct device *d,
542 struct device_attribute *attr,
543 char *buf)
b76cdba9
MW
544{
545 int count = 0;
43cb76d9 546 struct bonding *bond = to_bond(d);
b76cdba9 547
01844098 548 if (BOND_MODE(bond) == BOND_MODE_8023AD) {
b76cdba9 549 struct ad_info ad_info;
3d632c3f 550 count = sprintf(buf, "%d\n",
318debd8 551 bond_3ad_get_active_agg_info(bond, &ad_info)
3d632c3f 552 ? 0 : ad_info.actor_key);
b76cdba9 553 }
b76cdba9
MW
554
555 return count;
556}
43cb76d9 557static DEVICE_ATTR(ad_actor_key, S_IRUGO, bonding_show_ad_actor_key, NULL);
b76cdba9
MW
558
559
dc3e5d18 560/* Show current 802.3ad partner key. */
43cb76d9
GKH
561static ssize_t bonding_show_ad_partner_key(struct device *d,
562 struct device_attribute *attr,
563 char *buf)
b76cdba9
MW
564{
565 int count = 0;
43cb76d9 566 struct bonding *bond = to_bond(d);
b76cdba9 567
01844098 568 if (BOND_MODE(bond) == BOND_MODE_8023AD) {
b76cdba9 569 struct ad_info ad_info;
3d632c3f 570 count = sprintf(buf, "%d\n",
318debd8 571 bond_3ad_get_active_agg_info(bond, &ad_info)
3d632c3f 572 ? 0 : ad_info.partner_key);
b76cdba9 573 }
b76cdba9
MW
574
575 return count;
576}
43cb76d9 577static DEVICE_ATTR(ad_partner_key, S_IRUGO, bonding_show_ad_partner_key, NULL);
b76cdba9
MW
578
579
dc3e5d18 580/* Show current 802.3ad partner mac. */
43cb76d9
GKH
581static ssize_t bonding_show_ad_partner_mac(struct device *d,
582 struct device_attribute *attr,
583 char *buf)
b76cdba9
MW
584{
585 int count = 0;
43cb76d9 586 struct bonding *bond = to_bond(d);
b76cdba9 587
01844098 588 if (BOND_MODE(bond) == BOND_MODE_8023AD) {
b76cdba9 589 struct ad_info ad_info;
3d632c3f 590 if (!bond_3ad_get_active_agg_info(bond, &ad_info))
e174961c 591 count = sprintf(buf, "%pM\n", ad_info.partner_system);
b76cdba9 592 }
b76cdba9
MW
593
594 return count;
595}
43cb76d9 596static DEVICE_ATTR(ad_partner_mac, S_IRUGO, bonding_show_ad_partner_mac, NULL);
b76cdba9 597
dc3e5d18 598/* Show the queue_ids of the slaves in the current bond. */
bb1d9123
AG
599static ssize_t bonding_show_queue_id(struct device *d,
600 struct device_attribute *attr,
601 char *buf)
602{
bb1d9123 603 struct bonding *bond = to_bond(d);
9caff1e7 604 struct list_head *iter;
dec1e90e 605 struct slave *slave;
606 int res = 0;
bb1d9123
AG
607
608 if (!rtnl_trylock())
609 return restart_syscall();
610
9caff1e7 611 bond_for_each_slave(bond, slave, iter) {
79236680
NP
612 if (res > (PAGE_SIZE - IFNAMSIZ - 6)) {
613 /* not enough space for another interface_name:queue_id pair */
bb1d9123
AG
614 if ((PAGE_SIZE - res) > 10)
615 res = PAGE_SIZE - 10;
616 res += sprintf(buf + res, "++more++ ");
617 break;
618 }
619 res += sprintf(buf + res, "%s:%d ",
620 slave->dev->name, slave->queue_id);
621 }
bb1d9123
AG
622 if (res)
623 buf[res-1] = '\n'; /* eat the leftover space */
4d1ae5fb 624
bb1d9123 625 rtnl_unlock();
dec1e90e 626
bb1d9123
AG
627 return res;
628}
bb1d9123 629static DEVICE_ATTR(queue_id, S_IRUGO | S_IWUSR, bonding_show_queue_id,
dc3e5d18 630 bonding_sysfs_store_option);
bb1d9123
AG
631
632
dc3e5d18 633/* Show the all_slaves_active flag. */
ebd8e497
AG
634static ssize_t bonding_show_slaves_active(struct device *d,
635 struct device_attribute *attr,
636 char *buf)
637{
638 struct bonding *bond = to_bond(d);
639
640 return sprintf(buf, "%d\n", bond->params.all_slaves_active);
641}
ebd8e497 642static DEVICE_ATTR(all_slaves_active, S_IRUGO | S_IWUSR,
dc3e5d18 643 bonding_show_slaves_active, bonding_sysfs_store_option);
b76cdba9 644
dc3e5d18 645/* Show the number of IGMP membership reports to send on link failure */
c2952c31 646static ssize_t bonding_show_resend_igmp(struct device *d,
94265cf5
FL
647 struct device_attribute *attr,
648 char *buf)
c2952c31
FL
649{
650 struct bonding *bond = to_bond(d);
651
652 return sprintf(buf, "%d\n", bond->params.resend_igmp);
653}
c2952c31 654static DEVICE_ATTR(resend_igmp, S_IRUGO | S_IWUSR,
dc3e5d18 655 bonding_show_resend_igmp, bonding_sysfs_store_option);
c2952c31 656
7eacd038
NH
657
658static ssize_t bonding_show_lp_interval(struct device *d,
659 struct device_attribute *attr,
660 char *buf)
661{
662 struct bonding *bond = to_bond(d);
8d836d09 663
dc3e5d18 664 return sprintf(buf, "%d\n", bond->params.lp_interval);
7eacd038 665}
7eacd038 666static DEVICE_ATTR(lp_interval, S_IRUGO | S_IWUSR,
dc3e5d18 667 bonding_show_lp_interval, bonding_sysfs_store_option);
7eacd038 668
e9f0fb88
MB
669static ssize_t bonding_show_tlb_dynamic_lb(struct device *d,
670 struct device_attribute *attr,
671 char *buf)
672{
673 struct bonding *bond = to_bond(d);
674 return sprintf(buf, "%d\n", bond->params.tlb_dynamic_lb);
675}
e9f0fb88 676static DEVICE_ATTR(tlb_dynamic_lb, S_IRUGO | S_IWUSR,
dc3e5d18 677 bonding_show_tlb_dynamic_lb, bonding_sysfs_store_option);
e9f0fb88 678
73958329
NA
679static ssize_t bonding_show_packets_per_slave(struct device *d,
680 struct device_attribute *attr,
681 char *buf)
682{
683 struct bonding *bond = to_bond(d);
a752a8b9 684 unsigned int packets_per_slave = bond->params.packets_per_slave;
c13ab3ff 685
dc3e5d18 686 return sprintf(buf, "%u\n", packets_per_slave);
73958329 687}
73958329 688static DEVICE_ATTR(packets_per_slave, S_IRUGO | S_IWUSR,
dc3e5d18 689 bonding_show_packets_per_slave, bonding_sysfs_store_option);
73958329 690
b76cdba9 691static struct attribute *per_bond_attrs[] = {
43cb76d9
GKH
692 &dev_attr_slaves.attr,
693 &dev_attr_mode.attr,
dd957c57 694 &dev_attr_fail_over_mac.attr,
43cb76d9 695 &dev_attr_arp_validate.attr,
8599b52e 696 &dev_attr_arp_all_targets.attr,
43cb76d9
GKH
697 &dev_attr_arp_interval.attr,
698 &dev_attr_arp_ip_target.attr,
699 &dev_attr_downdelay.attr,
700 &dev_attr_updelay.attr,
701 &dev_attr_lacp_rate.attr,
fd989c83 702 &dev_attr_ad_select.attr,
43cb76d9 703 &dev_attr_xmit_hash_policy.attr,
ad246c99
BH
704 &dev_attr_num_grat_arp.attr,
705 &dev_attr_num_unsol_na.attr,
43cb76d9
GKH
706 &dev_attr_miimon.attr,
707 &dev_attr_primary.attr,
a549952a 708 &dev_attr_primary_reselect.attr,
43cb76d9
GKH
709 &dev_attr_use_carrier.attr,
710 &dev_attr_active_slave.attr,
711 &dev_attr_mii_status.attr,
712 &dev_attr_ad_aggregator.attr,
713 &dev_attr_ad_num_ports.attr,
714 &dev_attr_ad_actor_key.attr,
715 &dev_attr_ad_partner_key.attr,
716 &dev_attr_ad_partner_mac.attr,
bb1d9123 717 &dev_attr_queue_id.attr,
ebd8e497 718 &dev_attr_all_slaves_active.attr,
c2952c31 719 &dev_attr_resend_igmp.attr,
655f8919 720 &dev_attr_min_links.attr,
7eacd038 721 &dev_attr_lp_interval.attr,
73958329 722 &dev_attr_packets_per_slave.attr,
e9f0fb88 723 &dev_attr_tlb_dynamic_lb.attr,
b76cdba9
MW
724 NULL,
725};
726
727static struct attribute_group bonding_group = {
728 .name = "bonding",
729 .attrs = per_bond_attrs,
730};
731
dc3e5d18 732/* Initialize sysfs. This sets up the bonding_masters file in
b76cdba9
MW
733 * /sys/class/net.
734 */
4c22400a 735int bond_create_sysfs(struct bond_net *bn)
b76cdba9 736{
b8a9787e 737 int ret;
b76cdba9 738
4c22400a 739 bn->class_attr_bonding_masters = class_attr_bonding_masters;
01718e36 740 sysfs_attr_init(&bn->class_attr_bonding_masters.attr);
4c22400a 741
58292cbe
TH
742 ret = netdev_class_create_file_ns(&bn->class_attr_bonding_masters,
743 bn->net);
dc3e5d18 744 /* Permit multiple loads of the module by ignoring failures to
877cbd36
JV
745 * create the bonding_masters sysfs file. Bonding devices
746 * created by second or subsequent loads of the module will
747 * not be listed in, or controllable by, bonding_masters, but
748 * will have the usual "bonding" sysfs directory.
749 *
750 * This is done to preserve backwards compatibility for
751 * initscripts/sysconfig, which load bonding multiple times to
752 * configure multiple bonding devices.
753 */
754 if (ret == -EEXIST) {
38d2f38b 755 /* Is someone being kinky and naming a device bonding_master? */
4c22400a 756 if (__dev_get_by_name(bn->net,
38d2f38b 757 class_attr_bonding_masters.attr.name))
90194264 758 pr_err("network device named %s already exists in sysfs\n",
38d2f38b 759 class_attr_bonding_masters.attr.name);
130aa61a 760 ret = 0;
877cbd36 761 }
b76cdba9
MW
762
763 return ret;
764
765}
766
dc3e5d18 767/* Remove /sys/class/net/bonding_masters. */
4c22400a 768void bond_destroy_sysfs(struct bond_net *bn)
b76cdba9 769{
58292cbe 770 netdev_class_remove_file_ns(&bn->class_attr_bonding_masters, bn->net);
b76cdba9
MW
771}
772
dc3e5d18 773/* Initialize sysfs for each bond. This sets up and registers
b76cdba9
MW
774 * the 'bondctl' directory for each individual bond under /sys/class/net.
775 */
6151b3d4 776void bond_prepare_sysfs_group(struct bonding *bond)
b76cdba9 777{
6151b3d4 778 bond->dev->sysfs_groups[0] = &bonding_group;
b76cdba9
MW
779}
780