aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAmerigo Wang <amwang@redhat.com>2011-03-06 16:58:46 -0500
committerDavid S. Miller <davem@davemloft.net>2011-03-09 16:32:17 -0500
commitbd33acc3cc525972ac779067e98efb26516c5b94 (patch)
treeba11a65bb14001f390abe15644c7397c7ffc4935
parenta015f6f49968c330b236ca2f6c2170820414f922 (diff)
bonding: move procfs code into bond_procfs.c
V2: Move #ifdef CONFIG_PROC_FS into bonding.h, as suggested by David. bond_main.c is bloating, separate the procfs code out, move them to bond_procfs.c Signed-off-by: WANG Cong <amwang@redhat.com> Reviewed-by: Jiri Pirko <jpirko@redhat.com> Signed-off-by: Andy Gospodarek <andy@greyhouse.net> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/bonding/Makefile3
-rw-r--r--drivers/net/bonding/bond_main.c302
-rw-r--r--drivers/net/bonding/bond_procfs.c275
-rw-r--r--drivers/net/bonding/bonding.h26
4 files changed, 306 insertions, 300 deletions
diff --git a/drivers/net/bonding/Makefile b/drivers/net/bonding/Makefile
index 0e2737eac8b7..3c5c014e82b2 100644
--- a/drivers/net/bonding/Makefile
+++ b/drivers/net/bonding/Makefile
@@ -6,6 +6,9 @@ obj-$(CONFIG_BONDING) += bonding.o
6 6
7bonding-objs := bond_main.o bond_3ad.o bond_alb.o bond_sysfs.o bond_debugfs.o 7bonding-objs := bond_main.o bond_3ad.o bond_alb.o bond_sysfs.o bond_debugfs.o
8 8
9proc-$(CONFIG_PROC_FS) += bond_procfs.o
10bonding-objs += $(proc-y)
11
9ipv6-$(subst m,y,$(CONFIG_IPV6)) += bond_ipv6.o 12ipv6-$(subst m,y,$(CONFIG_IPV6)) += bond_ipv6.o
10bonding-objs += $(ipv6-y) 13bonding-objs += $(ipv6-y)
11 14
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index 7b7ca971672f..68a5ce0a649f 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -65,8 +65,6 @@
65#include <linux/skbuff.h> 65#include <linux/skbuff.h>
66#include <net/sock.h> 66#include <net/sock.h>
67#include <linux/rtnetlink.h> 67#include <linux/rtnetlink.h>
68#include <linux/proc_fs.h>
69#include <linux/seq_file.h>
70#include <linux/smp.h> 68#include <linux/smp.h>
71#include <linux/if_ether.h> 69#include <linux/if_ether.h>
72#include <net/arp.h> 70#include <net/arp.h>
@@ -173,9 +171,6 @@ MODULE_PARM_DESC(resend_igmp, "Number of IGMP membership reports to send on link
173atomic_t netpoll_block_tx = ATOMIC_INIT(0); 171atomic_t netpoll_block_tx = ATOMIC_INIT(0);
174#endif 172#endif
175 173
176static const char * const version =
177 DRV_DESCRIPTION ": v" DRV_VERSION " (" DRV_RELDATE ")\n";
178
179int bond_net_id __read_mostly; 174int bond_net_id __read_mostly;
180 175
181static __be32 arp_target[BOND_MAX_ARP_TARGETS]; 176static __be32 arp_target[BOND_MAX_ARP_TARGETS];
@@ -245,7 +240,7 @@ static void bond_uninit(struct net_device *bond_dev);
245 240
246/*---------------------------- General routines -----------------------------*/ 241/*---------------------------- General routines -----------------------------*/
247 242
248static const char *bond_mode_name(int mode) 243const char *bond_mode_name(int mode)
249{ 244{
250 static const char *names[] = { 245 static const char *names[] = {
251 [BOND_MODE_ROUNDROBIN] = "load balancing (round-robin)", 246 [BOND_MODE_ROUNDROBIN] = "load balancing (round-robin)",
@@ -3288,299 +3283,6 @@ out:
3288 read_unlock(&bond->lock); 3283 read_unlock(&bond->lock);
3289} 3284}
3290 3285
3291/*------------------------------ proc/seq_file-------------------------------*/
3292
3293#ifdef CONFIG_PROC_FS
3294
3295static void *bond_info_seq_start(struct seq_file *seq, loff_t *pos)
3296 __acquires(RCU)
3297 __acquires(&bond->lock)
3298{
3299 struct bonding *bond = seq->private;
3300 loff_t off = 0;
3301 struct slave *slave;
3302 int i;
3303
3304 /* make sure the bond won't be taken away */
3305 rcu_read_lock();
3306 read_lock(&bond->lock);
3307
3308 if (*pos == 0)
3309 return SEQ_START_TOKEN;
3310
3311 bond_for_each_slave(bond, slave, i) {
3312 if (++off == *pos)
3313 return slave;
3314 }
3315
3316 return NULL;
3317}
3318
3319static void *bond_info_seq_next(struct seq_file *seq, void *v, loff_t *pos)
3320{
3321 struct bonding *bond = seq->private;
3322 struct slave *slave = v;
3323
3324 ++*pos;
3325 if (v == SEQ_START_TOKEN)
3326 return bond->first_slave;
3327
3328 slave = slave->next;
3329
3330 return (slave == bond->first_slave) ? NULL : slave;
3331}
3332
3333static void bond_info_seq_stop(struct seq_file *seq, void *v)
3334 __releases(&bond->lock)
3335 __releases(RCU)
3336{
3337 struct bonding *bond = seq->private;
3338
3339 read_unlock(&bond->lock);
3340 rcu_read_unlock();
3341}
3342
3343static void bond_info_show_master(struct seq_file *seq)
3344{
3345 struct bonding *bond = seq->private;
3346 struct slave *curr;
3347 int i;
3348
3349 read_lock(&bond->curr_slave_lock);
3350 curr = bond->curr_active_slave;
3351 read_unlock(&bond->curr_slave_lock);
3352
3353 seq_printf(seq, "Bonding Mode: %s",
3354 bond_mode_name(bond->params.mode));
3355
3356 if (bond->params.mode == BOND_MODE_ACTIVEBACKUP &&
3357 bond->params.fail_over_mac)
3358 seq_printf(seq, " (fail_over_mac %s)",
3359 fail_over_mac_tbl[bond->params.fail_over_mac].modename);
3360
3361 seq_printf(seq, "\n");
3362
3363 if (bond->params.mode == BOND_MODE_XOR ||
3364 bond->params.mode == BOND_MODE_8023AD) {
3365 seq_printf(seq, "Transmit Hash Policy: %s (%d)\n",
3366 xmit_hashtype_tbl[bond->params.xmit_policy].modename,
3367 bond->params.xmit_policy);
3368 }
3369
3370 if (USES_PRIMARY(bond->params.mode)) {
3371 seq_printf(seq, "Primary Slave: %s",
3372 (bond->primary_slave) ?
3373 bond->primary_slave->dev->name : "None");
3374 if (bond->primary_slave)
3375 seq_printf(seq, " (primary_reselect %s)",
3376 pri_reselect_tbl[bond->params.primary_reselect].modename);
3377
3378 seq_printf(seq, "\nCurrently Active Slave: %s\n",
3379 (curr) ? curr->dev->name : "None");
3380 }
3381
3382 seq_printf(seq, "MII Status: %s\n", netif_carrier_ok(bond->dev) ?
3383 "up" : "down");
3384 seq_printf(seq, "MII Polling Interval (ms): %d\n", bond->params.miimon);
3385 seq_printf(seq, "Up Delay (ms): %d\n",
3386 bond->params.updelay * bond->params.miimon);
3387 seq_printf(seq, "Down Delay (ms): %d\n",
3388 bond->params.downdelay * bond->params.miimon);
3389
3390
3391 /* ARP information */
3392 if (bond->params.arp_interval > 0) {
3393 int printed = 0;
3394 seq_printf(seq, "ARP Polling Interval (ms): %d\n",
3395 bond->params.arp_interval);
3396
3397 seq_printf(seq, "ARP IP target/s (n.n.n.n form):");
3398
3399 for (i = 0; (i < BOND_MAX_ARP_TARGETS); i++) {
3400 if (!bond->params.arp_targets[i])
3401 break;
3402 if (printed)
3403 seq_printf(seq, ",");
3404 seq_printf(seq, " %pI4", &bond->params.arp_targets[i]);
3405 printed = 1;
3406 }
3407 seq_printf(seq, "\n");
3408 }
3409
3410 if (bond->params.mode == BOND_MODE_8023AD) {
3411 struct ad_info ad_info;
3412
3413 seq_puts(seq, "\n802.3ad info\n");
3414 seq_printf(seq, "LACP rate: %s\n",
3415 (bond->params.lacp_fast) ? "fast" : "slow");
3416 seq_printf(seq, "Aggregator selection policy (ad_select): %s\n",
3417 ad_select_tbl[bond->params.ad_select].modename);
3418
3419 if (bond_3ad_get_active_agg_info(bond, &ad_info)) {
3420 seq_printf(seq, "bond %s has no active aggregator\n",
3421 bond->dev->name);
3422 } else {
3423 seq_printf(seq, "Active Aggregator Info:\n");
3424
3425 seq_printf(seq, "\tAggregator ID: %d\n",
3426 ad_info.aggregator_id);
3427 seq_printf(seq, "\tNumber of ports: %d\n",
3428 ad_info.ports);
3429 seq_printf(seq, "\tActor Key: %d\n",
3430 ad_info.actor_key);
3431 seq_printf(seq, "\tPartner Key: %d\n",
3432 ad_info.partner_key);
3433 seq_printf(seq, "\tPartner Mac Address: %pM\n",
3434 ad_info.partner_system);
3435 }
3436 }
3437}
3438
3439static void bond_info_show_slave(struct seq_file *seq,
3440 const struct slave *slave)
3441{
3442 struct bonding *bond = seq->private;
3443
3444 seq_printf(seq, "\nSlave Interface: %s\n", slave->dev->name);
3445 seq_printf(seq, "MII Status: %s\n",
3446 (slave->link == BOND_LINK_UP) ? "up" : "down");
3447 seq_printf(seq, "Speed: %d Mbps\n", slave->speed);
3448 seq_printf(seq, "Duplex: %s\n", slave->duplex ? "full" : "half");
3449 seq_printf(seq, "Link Failure Count: %u\n",
3450 slave->link_failure_count);
3451
3452 seq_printf(seq, "Permanent HW addr: %pM\n", slave->perm_hwaddr);
3453
3454 if (bond->params.mode == BOND_MODE_8023AD) {
3455 const struct aggregator *agg
3456 = SLAVE_AD_INFO(slave).port.aggregator;
3457
3458 if (agg)
3459 seq_printf(seq, "Aggregator ID: %d\n",
3460 agg->aggregator_identifier);
3461 else
3462 seq_puts(seq, "Aggregator ID: N/A\n");
3463 }
3464 seq_printf(seq, "Slave queue ID: %d\n", slave->queue_id);
3465}
3466
3467static int bond_info_seq_show(struct seq_file *seq, void *v)
3468{
3469 if (v == SEQ_START_TOKEN) {
3470 seq_printf(seq, "%s\n", version);
3471 bond_info_show_master(seq);
3472 } else
3473 bond_info_show_slave(seq, v);
3474
3475 return 0;
3476}
3477
3478static const struct seq_operations bond_info_seq_ops = {
3479 .start = bond_info_seq_start,
3480 .next = bond_info_seq_next,
3481 .stop = bond_info_seq_stop,
3482 .show = bond_info_seq_show,
3483};
3484
3485static int bond_info_open(struct inode *inode, struct file *file)
3486{
3487 struct seq_file *seq;
3488 struct proc_dir_entry *proc;
3489 int res;
3490
3491 res = seq_open(file, &bond_info_seq_ops);
3492 if (!res) {
3493 /* recover the pointer buried in proc_dir_entry data */
3494 seq = file->private_data;
3495 proc = PDE(inode);
3496 seq->private = proc->data;
3497 }
3498
3499 return res;
3500}
3501
3502static const struct file_operations bond_info_fops = {
3503 .owner = THIS_MODULE,
3504 .open = bond_info_open,
3505 .read = seq_read,
3506 .llseek = seq_lseek,
3507 .release = seq_release,
3508};
3509
3510static void bond_create_proc_entry(struct bonding *bond)
3511{
3512 struct net_device *bond_dev = bond->dev;
3513 struct bond_net *bn = net_generic(dev_net(bond_dev), bond_net_id);
3514
3515 if (bn->proc_dir) {
3516 bond->proc_entry = proc_create_data(bond_dev->name,
3517 S_IRUGO, bn->proc_dir,
3518 &bond_info_fops, bond);
3519 if (bond->proc_entry == NULL)
3520 pr_warning("Warning: Cannot create /proc/net/%s/%s\n",
3521 DRV_NAME, bond_dev->name);
3522 else
3523 memcpy(bond->proc_file_name, bond_dev->name, IFNAMSIZ);
3524 }
3525}
3526
3527static void bond_remove_proc_entry(struct bonding *bond)
3528{
3529 struct net_device *bond_dev = bond->dev;
3530 struct bond_net *bn = net_generic(dev_net(bond_dev), bond_net_id);
3531
3532 if (bn->proc_dir && bond->proc_entry) {
3533 remove_proc_entry(bond->proc_file_name, bn->proc_dir);
3534 memset(bond->proc_file_name, 0, IFNAMSIZ);
3535 bond->proc_entry = NULL;
3536 }
3537}
3538
3539/* Create the bonding directory under /proc/net, if doesn't exist yet.
3540 * Caller must hold rtnl_lock.
3541 */
3542static void __net_init bond_create_proc_dir(struct bond_net *bn)
3543{
3544 if (!bn->proc_dir) {
3545 bn->proc_dir = proc_mkdir(DRV_NAME, bn->net->proc_net);
3546 if (!bn->proc_dir)
3547 pr_warning("Warning: cannot create /proc/net/%s\n",
3548 DRV_NAME);
3549 }
3550}
3551
3552/* Destroy the bonding directory under /proc/net, if empty.
3553 * Caller must hold rtnl_lock.
3554 */
3555static void __net_exit bond_destroy_proc_dir(struct bond_net *bn)
3556{
3557 if (bn->proc_dir) {
3558 remove_proc_entry(DRV_NAME, bn->net->proc_net);
3559 bn->proc_dir = NULL;
3560 }
3561}
3562
3563#else /* !CONFIG_PROC_FS */
3564
3565static void bond_create_proc_entry(struct bonding *bond)
3566{
3567}
3568
3569static void bond_remove_proc_entry(struct bonding *bond)
3570{
3571}
3572
3573static inline void bond_create_proc_dir(struct bond_net *bn)
3574{
3575}
3576
3577static inline void bond_destroy_proc_dir(struct bond_net *bn)
3578{
3579}
3580
3581#endif /* CONFIG_PROC_FS */
3582
3583
3584/*-------------------------- netdev event handling --------------------------*/ 3286/*-------------------------- netdev event handling --------------------------*/
3585 3287
3586/* 3288/*
@@ -5384,7 +5086,7 @@ static int __init bonding_init(void)
5384 int i; 5086 int i;
5385 int res; 5087 int res;
5386 5088
5387 pr_info("%s", version); 5089 pr_info("%s", bond_version);
5388 5090
5389 res = bond_check_params(&bonding_defaults); 5091 res = bond_check_params(&bonding_defaults);
5390 if (res) 5092 if (res)
diff --git a/drivers/net/bonding/bond_procfs.c b/drivers/net/bonding/bond_procfs.c
new file mode 100644
index 000000000000..c32ff55a34c1
--- /dev/null
+++ b/drivers/net/bonding/bond_procfs.c
@@ -0,0 +1,275 @@
1#include <linux/proc_fs.h>
2#include <net/net_namespace.h>
3#include <net/netns/generic.h>
4#include "bonding.h"
5
6
7extern const char *bond_mode_name(int mode);
8
9static void *bond_info_seq_start(struct seq_file *seq, loff_t *pos)
10 __acquires(RCU)
11 __acquires(&bond->lock)
12{
13 struct bonding *bond = seq->private;
14 loff_t off = 0;
15 struct slave *slave;
16 int i;
17
18 /* make sure the bond won't be taken away */
19 rcu_read_lock();
20 read_lock(&bond->lock);
21
22 if (*pos == 0)
23 return SEQ_START_TOKEN;
24
25 bond_for_each_slave(bond, slave, i) {
26 if (++off == *pos)
27 return slave;
28 }
29
30 return NULL;
31}
32
33static void *bond_info_seq_next(struct seq_file *seq, void *v, loff_t *pos)
34{
35 struct bonding *bond = seq->private;
36 struct slave *slave = v;
37
38 ++*pos;
39 if (v == SEQ_START_TOKEN)
40 return bond->first_slave;
41
42 slave = slave->next;
43
44 return (slave == bond->first_slave) ? NULL : slave;
45}
46
47static void bond_info_seq_stop(struct seq_file *seq, void *v)
48 __releases(&bond->lock)
49 __releases(RCU)
50{
51 struct bonding *bond = seq->private;
52
53 read_unlock(&bond->lock);
54 rcu_read_unlock();
55}
56
57static void bond_info_show_master(struct seq_file *seq)
58{
59 struct bonding *bond = seq->private;
60 struct slave *curr;
61 int i;
62
63 read_lock(&bond->curr_slave_lock);
64 curr = bond->curr_active_slave;
65 read_unlock(&bond->curr_slave_lock);
66
67 seq_printf(seq, "Bonding Mode: %s",
68 bond_mode_name(bond->params.mode));
69
70 if (bond->params.mode == BOND_MODE_ACTIVEBACKUP &&
71 bond->params.fail_over_mac)
72 seq_printf(seq, " (fail_over_mac %s)",
73 fail_over_mac_tbl[bond->params.fail_over_mac].modename);
74
75 seq_printf(seq, "\n");
76
77 if (bond->params.mode == BOND_MODE_XOR ||
78 bond->params.mode == BOND_MODE_8023AD) {
79 seq_printf(seq, "Transmit Hash Policy: %s (%d)\n",
80 xmit_hashtype_tbl[bond->params.xmit_policy].modename,
81 bond->params.xmit_policy);
82 }
83
84 if (USES_PRIMARY(bond->params.mode)) {
85 seq_printf(seq, "Primary Slave: %s",
86 (bond->primary_slave) ?
87 bond->primary_slave->dev->name : "None");
88 if (bond->primary_slave)
89 seq_printf(seq, " (primary_reselect %s)",
90 pri_reselect_tbl[bond->params.primary_reselect].modename);
91
92 seq_printf(seq, "\nCurrently Active Slave: %s\n",
93 (curr) ? curr->dev->name : "None");
94 }
95
96 seq_printf(seq, "MII Status: %s\n", netif_carrier_ok(bond->dev) ?
97 "up" : "down");
98 seq_printf(seq, "MII Polling Interval (ms): %d\n", bond->params.miimon);
99 seq_printf(seq, "Up Delay (ms): %d\n",
100 bond->params.updelay * bond->params.miimon);
101 seq_printf(seq, "Down Delay (ms): %d\n",
102 bond->params.downdelay * bond->params.miimon);
103
104
105 /* ARP information */
106 if (bond->params.arp_interval > 0) {
107 int printed = 0;
108 seq_printf(seq, "ARP Polling Interval (ms): %d\n",
109 bond->params.arp_interval);
110
111 seq_printf(seq, "ARP IP target/s (n.n.n.n form):");
112
113 for (i = 0; (i < BOND_MAX_ARP_TARGETS); i++) {
114 if (!bond->params.arp_targets[i])
115 break;
116 if (printed)
117 seq_printf(seq, ",");
118 seq_printf(seq, " %pI4", &bond->params.arp_targets[i]);
119 printed = 1;
120 }
121 seq_printf(seq, "\n");
122 }
123
124 if (bond->params.mode == BOND_MODE_8023AD) {
125 struct ad_info ad_info;
126
127 seq_puts(seq, "\n802.3ad info\n");
128 seq_printf(seq, "LACP rate: %s\n",
129 (bond->params.lacp_fast) ? "fast" : "slow");
130 seq_printf(seq, "Aggregator selection policy (ad_select): %s\n",
131 ad_select_tbl[bond->params.ad_select].modename);
132
133 if (bond_3ad_get_active_agg_info(bond, &ad_info)) {
134 seq_printf(seq, "bond %s has no active aggregator\n",
135 bond->dev->name);
136 } else {
137 seq_printf(seq, "Active Aggregator Info:\n");
138
139 seq_printf(seq, "\tAggregator ID: %d\n",
140 ad_info.aggregator_id);
141 seq_printf(seq, "\tNumber of ports: %d\n",
142 ad_info.ports);
143 seq_printf(seq, "\tActor Key: %d\n",
144 ad_info.actor_key);
145 seq_printf(seq, "\tPartner Key: %d\n",
146 ad_info.partner_key);
147 seq_printf(seq, "\tPartner Mac Address: %pM\n",
148 ad_info.partner_system);
149 }
150 }
151}
152
153static void bond_info_show_slave(struct seq_file *seq,
154 const struct slave *slave)
155{
156 struct bonding *bond = seq->private;
157
158 seq_printf(seq, "\nSlave Interface: %s\n", slave->dev->name);
159 seq_printf(seq, "MII Status: %s\n",
160 (slave->link == BOND_LINK_UP) ? "up" : "down");
161 seq_printf(seq, "Speed: %d Mbps\n", slave->speed);
162 seq_printf(seq, "Duplex: %s\n", slave->duplex ? "full" : "half");
163 seq_printf(seq, "Link Failure Count: %u\n",
164 slave->link_failure_count);
165
166 seq_printf(seq, "Permanent HW addr: %pM\n", slave->perm_hwaddr);
167
168 if (bond->params.mode == BOND_MODE_8023AD) {
169 const struct aggregator *agg
170 = SLAVE_AD_INFO(slave).port.aggregator;
171
172 if (agg)
173 seq_printf(seq, "Aggregator ID: %d\n",
174 agg->aggregator_identifier);
175 else
176 seq_puts(seq, "Aggregator ID: N/A\n");
177 }
178 seq_printf(seq, "Slave queue ID: %d\n", slave->queue_id);
179}
180
181static int bond_info_seq_show(struct seq_file *seq, void *v)
182{
183 if (v == SEQ_START_TOKEN) {
184 seq_printf(seq, "%s\n", bond_version);
185 bond_info_show_master(seq);
186 } else
187 bond_info_show_slave(seq, v);
188
189 return 0;
190}
191
192static const struct seq_operations bond_info_seq_ops = {
193 .start = bond_info_seq_start,
194 .next = bond_info_seq_next,
195 .stop = bond_info_seq_stop,
196 .show = bond_info_seq_show,
197};
198
199static int bond_info_open(struct inode *inode, struct file *file)
200{
201 struct seq_file *seq;
202 struct proc_dir_entry *proc;
203 int res;
204
205 res = seq_open(file, &bond_info_seq_ops);
206 if (!res) {
207 /* recover the pointer buried in proc_dir_entry data */
208 seq = file->private_data;
209 proc = PDE(inode);
210 seq->private = proc->data;
211 }
212
213 return res;
214}
215
216static const struct file_operations bond_info_fops = {
217 .owner = THIS_MODULE,
218 .open = bond_info_open,
219 .read = seq_read,
220 .llseek = seq_lseek,
221 .release = seq_release,
222};
223
224void bond_create_proc_entry(struct bonding *bond)
225{
226 struct net_device *bond_dev = bond->dev;
227 struct bond_net *bn = net_generic(dev_net(bond_dev), bond_net_id);
228
229 if (bn->proc_dir) {
230 bond->proc_entry = proc_create_data(bond_dev->name,
231 S_IRUGO, bn->proc_dir,
232 &bond_info_fops, bond);
233 if (bond->proc_entry == NULL)
234 pr_warning("Warning: Cannot create /proc/net/%s/%s\n",
235 DRV_NAME, bond_dev->name);
236 else
237 memcpy(bond->proc_file_name, bond_dev->name, IFNAMSIZ);
238 }
239}
240
241void bond_remove_proc_entry(struct bonding *bond)
242{
243 struct net_device *bond_dev = bond->dev;
244 struct bond_net *bn = net_generic(dev_net(bond_dev), bond_net_id);
245
246 if (bn->proc_dir && bond->proc_entry) {
247 remove_proc_entry(bond->proc_file_name, bn->proc_dir);
248 memset(bond->proc_file_name, 0, IFNAMSIZ);
249 bond->proc_entry = NULL;
250 }
251}
252
253/* Create the bonding directory under /proc/net, if doesn't exist yet.
254 * Caller must hold rtnl_lock.
255 */
256void __net_init bond_create_proc_dir(struct bond_net *bn)
257{
258 if (!bn->proc_dir) {
259 bn->proc_dir = proc_mkdir(DRV_NAME, bn->net->proc_net);
260 if (!bn->proc_dir)
261 pr_warning("Warning: cannot create /proc/net/%s\n",
262 DRV_NAME);
263 }
264}
265
266/* Destroy the bonding directory under /proc/net, if empty.
267 * Caller must hold rtnl_lock.
268 */
269void __net_exit bond_destroy_proc_dir(struct bond_net *bn)
270{
271 if (bn->proc_dir) {
272 remove_proc_entry(DRV_NAME, bn->net->proc_net);
273 bn->proc_dir = NULL;
274 }
275}
diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h
index ff4e26980220..c4e2343bb0b7 100644
--- a/drivers/net/bonding/bonding.h
+++ b/drivers/net/bonding/bonding.h
@@ -29,6 +29,8 @@
29#define DRV_NAME "bonding" 29#define DRV_NAME "bonding"
30#define DRV_DESCRIPTION "Ethernet Channel Bonding Driver" 30#define DRV_DESCRIPTION "Ethernet Channel Bonding Driver"
31 31
32#define bond_version DRV_DESCRIPTION ": v" DRV_VERSION " (" DRV_RELDATE ")\n"
33
32#define BOND_MAX_ARP_TARGETS 16 34#define BOND_MAX_ARP_TARGETS 16
33 35
34#define IS_UP(dev) \ 36#define IS_UP(dev) \
@@ -414,6 +416,30 @@ struct bond_net {
414#endif 416#endif
415}; 417};
416 418
419#ifdef CONFIG_PROC_FS
420void bond_create_proc_entry(struct bonding *bond);
421void bond_remove_proc_entry(struct bonding *bond);
422void bond_create_proc_dir(struct bond_net *bn);
423void bond_destroy_proc_dir(struct bond_net *bn);
424#else
425static inline void bond_create_proc_entry(struct bonding *bond)
426{
427}
428
429static inline void bond_remove_proc_entry(struct bonding *bond)
430{
431}
432
433static inline void bond_create_proc_dir(struct bond_net *bn)
434{
435}
436
437static inline void bond_destroy_proc_dir(struct bond_net *bn)
438{
439}
440#endif
441
442
417/* exported from bond_main.c */ 443/* exported from bond_main.c */
418extern int bond_net_id; 444extern int bond_net_id;
419extern const struct bond_parm_tbl bond_lacp_tbl[]; 445extern const struct bond_parm_tbl bond_lacp_tbl[];