1 #include <linux/proc_fs.h>
2 #include <net/net_namespace.h>
3 #include <net/netns/generic.h>
4 #include "bonding.h"
5 
6 
7 extern const char *bond_mode_name(int mode);
8 
bond_info_seq_start(struct seq_file * seq,loff_t * pos)9 static 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 
bond_info_seq_next(struct seq_file * seq,void * v,loff_t * pos)33 static 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 
bond_info_seq_stop(struct seq_file * seq,void * v)47 static 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 
bond_info_show_master(struct seq_file * seq)57 static 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 
bond_info_show_slave(struct seq_file * seq,const struct slave * slave)153 static 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 
bond_info_seq_show(struct seq_file * seq,void * v)181 static 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 
192 static 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 
bond_info_open(struct inode * inode,struct file * file)199 static 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 
216 static 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 
bond_create_proc_entry(struct bonding * bond)224 void 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 
bond_remove_proc_entry(struct bonding * bond)241 void 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  */
bond_create_proc_dir(struct bond_net * bn)256 void __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  */
bond_destroy_proc_dir(struct bond_net * bn)269 void __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 }
276