xref: /linux/drivers/net/bonding/bond_procfs.c (revision 4949009eb8d40a441dcddcd96e101e77d31cf1b2)
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 <net/bonding.h>
6 
7 
8 static void *bond_info_seq_start(struct seq_file *seq, loff_t *pos)
9 	__acquires(RCU)
10 {
11 	struct bonding *bond = seq->private;
12 	struct list_head *iter;
13 	struct slave *slave;
14 	loff_t off = 0;
15 
16 	rcu_read_lock();
17 
18 	if (*pos == 0)
19 		return SEQ_START_TOKEN;
20 
21 	bond_for_each_slave_rcu(bond, slave, iter)
22 		if (++off == *pos)
23 			return slave;
24 
25 	return NULL;
26 }
27 
28 static void *bond_info_seq_next(struct seq_file *seq, void *v, loff_t *pos)
29 {
30 	struct bonding *bond = seq->private;
31 	struct list_head *iter;
32 	struct slave *slave;
33 	bool found = false;
34 
35 	++*pos;
36 	if (v == SEQ_START_TOKEN)
37 		return bond_first_slave_rcu(bond);
38 
39 	bond_for_each_slave_rcu(bond, slave, iter) {
40 		if (found)
41 			return slave;
42 		if (slave == v)
43 			found = true;
44 	}
45 
46 	return NULL;
47 }
48 
49 static void bond_info_seq_stop(struct seq_file *seq, void *v)
50 	__releases(RCU)
51 {
52 	rcu_read_unlock();
53 }
54 
55 static void bond_info_show_master(struct seq_file *seq)
56 {
57 	struct bonding *bond = seq->private;
58 	const struct bond_opt_value *optval;
59 	struct slave *curr, *primary;
60 	int i;
61 
62 	curr = rcu_dereference(bond->curr_active_slave);
63 
64 	seq_printf(seq, "Bonding Mode: %s",
65 		   bond_mode_name(BOND_MODE(bond)));
66 
67 	if (BOND_MODE(bond) == BOND_MODE_ACTIVEBACKUP &&
68 	    bond->params.fail_over_mac) {
69 		optval = bond_opt_get_val(BOND_OPT_FAIL_OVER_MAC,
70 					  bond->params.fail_over_mac);
71 		seq_printf(seq, " (fail_over_mac %s)", optval->string);
72 	}
73 
74 	seq_printf(seq, "\n");
75 
76 	if (bond_mode_uses_xmit_hash(bond)) {
77 		optval = bond_opt_get_val(BOND_OPT_XMIT_HASH,
78 					  bond->params.xmit_policy);
79 		seq_printf(seq, "Transmit Hash Policy: %s (%d)\n",
80 			   optval->string, bond->params.xmit_policy);
81 	}
82 
83 	if (bond_uses_primary(bond)) {
84 		primary = rcu_dereference(bond->primary_slave);
85 		seq_printf(seq, "Primary Slave: %s",
86 			   primary ? primary->dev->name : "None");
87 		if (primary) {
88 			optval = bond_opt_get_val(BOND_OPT_PRIMARY_RESELECT,
89 						  bond->params.primary_reselect);
90 			seq_printf(seq, " (primary_reselect %s)",
91 				   optval->string);
92 		}
93 
94 		seq_printf(seq, "\nCurrently Active Slave: %s\n",
95 			   (curr) ? curr->dev->name : "None");
96 	}
97 
98 	seq_printf(seq, "MII Status: %s\n", netif_carrier_ok(bond->dev) ?
99 		   "up" : "down");
100 	seq_printf(seq, "MII Polling Interval (ms): %d\n", bond->params.miimon);
101 	seq_printf(seq, "Up Delay (ms): %d\n",
102 		   bond->params.updelay * bond->params.miimon);
103 	seq_printf(seq, "Down Delay (ms): %d\n",
104 		   bond->params.downdelay * bond->params.miimon);
105 
106 
107 	/* ARP information */
108 	if (bond->params.arp_interval > 0) {
109 		int printed = 0;
110 		seq_printf(seq, "ARP Polling Interval (ms): %d\n",
111 				bond->params.arp_interval);
112 
113 		seq_printf(seq, "ARP IP target/s (n.n.n.n form):");
114 
115 		for (i = 0; (i < BOND_MAX_ARP_TARGETS); i++) {
116 			if (!bond->params.arp_targets[i])
117 				break;
118 			if (printed)
119 				seq_printf(seq, ",");
120 			seq_printf(seq, " %pI4", &bond->params.arp_targets[i]);
121 			printed = 1;
122 		}
123 		seq_printf(seq, "\n");
124 	}
125 
126 	if (BOND_MODE(bond) == BOND_MODE_8023AD) {
127 		struct ad_info ad_info;
128 
129 		seq_puts(seq, "\n802.3ad info\n");
130 		seq_printf(seq, "LACP rate: %s\n",
131 			   (bond->params.lacp_fast) ? "fast" : "slow");
132 		seq_printf(seq, "Min links: %d\n", bond->params.min_links);
133 		optval = bond_opt_get_val(BOND_OPT_AD_SELECT,
134 					  bond->params.ad_select);
135 		seq_printf(seq, "Aggregator selection policy (ad_select): %s\n",
136 			   optval->string);
137 
138 		if (__bond_3ad_get_active_agg_info(bond, &ad_info)) {
139 			seq_printf(seq, "bond %s has no active aggregator\n",
140 				   bond->dev->name);
141 		} else {
142 			seq_printf(seq, "Active Aggregator Info:\n");
143 
144 			seq_printf(seq, "\tAggregator ID: %d\n",
145 				   ad_info.aggregator_id);
146 			seq_printf(seq, "\tNumber of ports: %d\n",
147 				   ad_info.ports);
148 			seq_printf(seq, "\tActor Key: %d\n",
149 				   ad_info.actor_key);
150 			seq_printf(seq, "\tPartner Key: %d\n",
151 				   ad_info.partner_key);
152 			seq_printf(seq, "\tPartner Mac Address: %pM\n",
153 				   ad_info.partner_system);
154 		}
155 	}
156 }
157 
158 static void bond_info_show_slave(struct seq_file *seq,
159 				 const struct slave *slave)
160 {
161 	struct bonding *bond = seq->private;
162 
163 	seq_printf(seq, "\nSlave Interface: %s\n", slave->dev->name);
164 	seq_printf(seq, "MII Status: %s\n", bond_slave_link_status(slave->link));
165 	if (slave->speed == SPEED_UNKNOWN)
166 		seq_printf(seq, "Speed: %s\n", "Unknown");
167 	else
168 		seq_printf(seq, "Speed: %d Mbps\n", slave->speed);
169 
170 	if (slave->duplex == DUPLEX_UNKNOWN)
171 		seq_printf(seq, "Duplex: %s\n", "Unknown");
172 	else
173 		seq_printf(seq, "Duplex: %s\n", slave->duplex ? "full" : "half");
174 
175 	seq_printf(seq, "Link Failure Count: %u\n",
176 		   slave->link_failure_count);
177 
178 	seq_printf(seq, "Permanent HW addr: %pM\n", slave->perm_hwaddr);
179 
180 	if (BOND_MODE(bond) == BOND_MODE_8023AD) {
181 		const struct aggregator *agg
182 			= SLAVE_AD_INFO(slave)->port.aggregator;
183 
184 		if (agg)
185 			seq_printf(seq, "Aggregator ID: %d\n",
186 				   agg->aggregator_identifier);
187 		else
188 			seq_puts(seq, "Aggregator ID: N/A\n");
189 	}
190 	seq_printf(seq, "Slave queue ID: %d\n", slave->queue_id);
191 }
192 
193 static int bond_info_seq_show(struct seq_file *seq, void *v)
194 {
195 	if (v == SEQ_START_TOKEN) {
196 		seq_printf(seq, "%s\n", bond_version);
197 		bond_info_show_master(seq);
198 	} else
199 		bond_info_show_slave(seq, v);
200 
201 	return 0;
202 }
203 
204 static const struct seq_operations bond_info_seq_ops = {
205 	.start = bond_info_seq_start,
206 	.next  = bond_info_seq_next,
207 	.stop  = bond_info_seq_stop,
208 	.show  = bond_info_seq_show,
209 };
210 
211 static int bond_info_open(struct inode *inode, struct file *file)
212 {
213 	struct seq_file *seq;
214 	int res;
215 
216 	res = seq_open(file, &bond_info_seq_ops);
217 	if (!res) {
218 		/* recover the pointer buried in proc_dir_entry data */
219 		seq = file->private_data;
220 		seq->private = PDE_DATA(inode);
221 	}
222 
223 	return res;
224 }
225 
226 static const struct file_operations bond_info_fops = {
227 	.owner   = THIS_MODULE,
228 	.open    = bond_info_open,
229 	.read    = seq_read,
230 	.llseek  = seq_lseek,
231 	.release = seq_release,
232 };
233 
234 void bond_create_proc_entry(struct bonding *bond)
235 {
236 	struct net_device *bond_dev = bond->dev;
237 	struct bond_net *bn = net_generic(dev_net(bond_dev), bond_net_id);
238 
239 	if (bn->proc_dir) {
240 		bond->proc_entry = proc_create_data(bond_dev->name,
241 						    S_IRUGO, bn->proc_dir,
242 						    &bond_info_fops, bond);
243 		if (bond->proc_entry == NULL)
244 			netdev_warn(bond_dev, "Cannot create /proc/net/%s/%s\n",
245 				    DRV_NAME, bond_dev->name);
246 		else
247 			memcpy(bond->proc_file_name, bond_dev->name, IFNAMSIZ);
248 	}
249 }
250 
251 void bond_remove_proc_entry(struct bonding *bond)
252 {
253 	struct net_device *bond_dev = bond->dev;
254 	struct bond_net *bn = net_generic(dev_net(bond_dev), bond_net_id);
255 
256 	if (bn->proc_dir && bond->proc_entry) {
257 		remove_proc_entry(bond->proc_file_name, bn->proc_dir);
258 		memset(bond->proc_file_name, 0, IFNAMSIZ);
259 		bond->proc_entry = NULL;
260 	}
261 }
262 
263 /* Create the bonding directory under /proc/net, if doesn't exist yet.
264  * Caller must hold rtnl_lock.
265  */
266 void __net_init bond_create_proc_dir(struct bond_net *bn)
267 {
268 	if (!bn->proc_dir) {
269 		bn->proc_dir = proc_mkdir(DRV_NAME, bn->net->proc_net);
270 		if (!bn->proc_dir)
271 			pr_warn("Warning: Cannot create /proc/net/%s\n",
272 				DRV_NAME);
273 	}
274 }
275 
276 /* Destroy the bonding directory under /proc/net, if empty.
277  * Caller must hold rtnl_lock.
278  */
279 void __net_exit bond_destroy_proc_dir(struct bond_net *bn)
280 {
281 	if (bn->proc_dir) {
282 		remove_proc_entry(DRV_NAME, bn->net->proc_net);
283 		bn->proc_dir = NULL;
284 	}
285 }
286