Merge branch 'for-3.11' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/libata
[cascardo/linux.git] / drivers / net / bonding / bond_procfs.c
1 #include <linux/proc_fs.h>
2 #include <linux/export.h>
3 #include <net/net_namespace.h>
4 #include <net/netns/generic.h>
5 #include "bonding.h"
6
7
8 static void *bond_info_seq_start(struct seq_file *seq, loff_t *pos)
9         __acquires(RCU)
10         __acquires(&bond->lock)
11 {
12         struct bonding *bond = seq->private;
13         loff_t off = 0;
14         struct slave *slave;
15         int i;
16
17         /* make sure the bond won't be taken away */
18         rcu_read_lock();
19         read_lock(&bond->lock);
20
21         if (*pos == 0)
22                 return SEQ_START_TOKEN;
23
24         bond_for_each_slave(bond, slave, i) {
25                 if (++off == *pos)
26                         return slave;
27         }
28
29         return NULL;
30 }
31
32 static void *bond_info_seq_next(struct seq_file *seq, void *v, loff_t *pos)
33 {
34         struct bonding *bond = seq->private;
35         struct slave *slave = v;
36
37         ++*pos;
38         if (v == SEQ_START_TOKEN)
39                 return bond->first_slave;
40
41         slave = slave->next;
42
43         return (slave == bond->first_slave) ? NULL : slave;
44 }
45
46 static void bond_info_seq_stop(struct seq_file *seq, void *v)
47         __releases(&bond->lock)
48         __releases(RCU)
49 {
50         struct bonding *bond = seq->private;
51
52         read_unlock(&bond->lock);
53         rcu_read_unlock();
54 }
55
56 static void bond_info_show_master(struct seq_file *seq)
57 {
58         struct bonding *bond = seq->private;
59         struct slave *curr;
60         int i;
61
62         read_lock(&bond->curr_slave_lock);
63         curr = bond->curr_active_slave;
64         read_unlock(&bond->curr_slave_lock);
65
66         seq_printf(seq, "Bonding Mode: %s",
67                    bond_mode_name(bond->params.mode));
68
69         if (bond->params.mode == BOND_MODE_ACTIVEBACKUP &&
70             bond->params.fail_over_mac)
71                 seq_printf(seq, " (fail_over_mac %s)",
72                    fail_over_mac_tbl[bond->params.fail_over_mac].modename);
73
74         seq_printf(seq, "\n");
75
76         if (bond->params.mode == BOND_MODE_XOR ||
77                 bond->params.mode == BOND_MODE_8023AD) {
78                 seq_printf(seq, "Transmit Hash Policy: %s (%d)\n",
79                         xmit_hashtype_tbl[bond->params.xmit_policy].modename,
80                         bond->params.xmit_policy);
81         }
82
83         if (USES_PRIMARY(bond->params.mode)) {
84                 seq_printf(seq, "Primary Slave: %s",
85                            (bond->primary_slave) ?
86                            bond->primary_slave->dev->name : "None");
87                 if (bond->primary_slave)
88                         seq_printf(seq, " (primary_reselect %s)",
89                    pri_reselect_tbl[bond->params.primary_reselect].modename);
90
91                 seq_printf(seq, "\nCurrently Active Slave: %s\n",
92                            (curr) ? curr->dev->name : "None");
93         }
94
95         seq_printf(seq, "MII Status: %s\n", netif_carrier_ok(bond->dev) ?
96                    "up" : "down");
97         seq_printf(seq, "MII Polling Interval (ms): %d\n", bond->params.miimon);
98         seq_printf(seq, "Up Delay (ms): %d\n",
99                    bond->params.updelay * bond->params.miimon);
100         seq_printf(seq, "Down Delay (ms): %d\n",
101                    bond->params.downdelay * bond->params.miimon);
102
103
104         /* ARP information */
105         if (bond->params.arp_interval > 0) {
106                 int printed = 0;
107                 seq_printf(seq, "ARP Polling Interval (ms): %d\n",
108                                 bond->params.arp_interval);
109
110                 seq_printf(seq, "ARP IP target/s (n.n.n.n form):");
111
112                 for (i = 0; (i < BOND_MAX_ARP_TARGETS); i++) {
113                         if (!bond->params.arp_targets[i])
114                                 break;
115                         if (printed)
116                                 seq_printf(seq, ",");
117                         seq_printf(seq, " %pI4", &bond->params.arp_targets[i]);
118                         printed = 1;
119                 }
120                 seq_printf(seq, "\n");
121         }
122
123         if (bond->params.mode == BOND_MODE_8023AD) {
124                 struct ad_info ad_info;
125
126                 seq_puts(seq, "\n802.3ad info\n");
127                 seq_printf(seq, "LACP rate: %s\n",
128                            (bond->params.lacp_fast) ? "fast" : "slow");
129                 seq_printf(seq, "Min links: %d\n", bond->params.min_links);
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
153 static const char *bond_slave_link_status(s8 link)
154 {
155         static const char * const status[] = {
156                 [BOND_LINK_UP] = "up",
157                 [BOND_LINK_FAIL] = "going down",
158                 [BOND_LINK_DOWN] = "down",
159                 [BOND_LINK_BACK] = "going back",
160         };
161
162         return status[link];
163 }
164
165 static void bond_info_show_slave(struct seq_file *seq,
166                                  const struct slave *slave)
167 {
168         struct bonding *bond = seq->private;
169
170         seq_printf(seq, "\nSlave Interface: %s\n", slave->dev->name);
171         seq_printf(seq, "MII Status: %s\n", bond_slave_link_status(slave->link));
172         if (slave->speed == SPEED_UNKNOWN)
173                 seq_printf(seq, "Speed: %s\n", "Unknown");
174         else
175                 seq_printf(seq, "Speed: %d Mbps\n", slave->speed);
176
177         if (slave->duplex == DUPLEX_UNKNOWN)
178                 seq_printf(seq, "Duplex: %s\n", "Unknown");
179         else
180                 seq_printf(seq, "Duplex: %s\n", slave->duplex ? "full" : "half");
181
182         seq_printf(seq, "Link Failure Count: %u\n",
183                    slave->link_failure_count);
184
185         seq_printf(seq, "Permanent HW addr: %pM\n", slave->perm_hwaddr);
186
187         if (bond->params.mode == BOND_MODE_8023AD) {
188                 const struct aggregator *agg
189                         = SLAVE_AD_INFO(slave).port.aggregator;
190
191                 if (agg)
192                         seq_printf(seq, "Aggregator ID: %d\n",
193                                    agg->aggregator_identifier);
194                 else
195                         seq_puts(seq, "Aggregator ID: N/A\n");
196         }
197         seq_printf(seq, "Slave queue ID: %d\n", slave->queue_id);
198 }
199
200 static int bond_info_seq_show(struct seq_file *seq, void *v)
201 {
202         if (v == SEQ_START_TOKEN) {
203                 seq_printf(seq, "%s\n", bond_version);
204                 bond_info_show_master(seq);
205         } else
206                 bond_info_show_slave(seq, v);
207
208         return 0;
209 }
210
211 static const struct seq_operations bond_info_seq_ops = {
212         .start = bond_info_seq_start,
213         .next  = bond_info_seq_next,
214         .stop  = bond_info_seq_stop,
215         .show  = bond_info_seq_show,
216 };
217
218 static int bond_info_open(struct inode *inode, struct file *file)
219 {
220         struct seq_file *seq;
221         int res;
222
223         res = seq_open(file, &bond_info_seq_ops);
224         if (!res) {
225                 /* recover the pointer buried in proc_dir_entry data */
226                 seq = file->private_data;
227                 seq->private = PDE_DATA(inode);
228         }
229
230         return res;
231 }
232
233 static const struct file_operations bond_info_fops = {
234         .owner   = THIS_MODULE,
235         .open    = bond_info_open,
236         .read    = seq_read,
237         .llseek  = seq_lseek,
238         .release = seq_release,
239 };
240
241 void bond_create_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) {
247                 bond->proc_entry = proc_create_data(bond_dev->name,
248                                                     S_IRUGO, bn->proc_dir,
249                                                     &bond_info_fops, bond);
250                 if (bond->proc_entry == NULL)
251                         pr_warning("Warning: Cannot create /proc/net/%s/%s\n",
252                                    DRV_NAME, bond_dev->name);
253                 else
254                         memcpy(bond->proc_file_name, bond_dev->name, IFNAMSIZ);
255         }
256 }
257
258 void bond_remove_proc_entry(struct bonding *bond)
259 {
260         struct net_device *bond_dev = bond->dev;
261         struct bond_net *bn = net_generic(dev_net(bond_dev), bond_net_id);
262
263         if (bn->proc_dir && bond->proc_entry) {
264                 remove_proc_entry(bond->proc_file_name, bn->proc_dir);
265                 memset(bond->proc_file_name, 0, IFNAMSIZ);
266                 bond->proc_entry = NULL;
267         }
268 }
269
270 /* Create the bonding directory under /proc/net, if doesn't exist yet.
271  * Caller must hold rtnl_lock.
272  */
273 void __net_init bond_create_proc_dir(struct bond_net *bn)
274 {
275         if (!bn->proc_dir) {
276                 bn->proc_dir = proc_mkdir(DRV_NAME, bn->net->proc_net);
277                 if (!bn->proc_dir)
278                         pr_warning("Warning: cannot create /proc/net/%s\n",
279                                    DRV_NAME);
280         }
281 }
282
283 /* Destroy the bonding directory under /proc/net, if empty.
284  * Caller must hold rtnl_lock.
285  */
286 void __net_exit bond_destroy_proc_dir(struct bond_net *bn)
287 {
288         if (bn->proc_dir) {
289                 remove_proc_entry(DRV_NAME, bn->net->proc_net);
290                 bn->proc_dir = NULL;
291         }
292 }