xref: /linux/net/bridge/br_sysfs_if.c (revision ef6af7bdb9e6c14eae8dc5fe852aefe1e089c85c)
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  *	Sysfs attributes of bridge ports
4  *	Linux ethernet bridge
5  *
6  *	Authors:
7  *	Stephen Hemminger		<shemminger@osdl.org>
8  */
9 
10 #include <linux/capability.h>
11 #include <linux/kernel.h>
12 #include <linux/netdevice.h>
13 #include <linux/if_bridge.h>
14 #include <linux/rtnetlink.h>
15 #include <linux/spinlock.h>
16 #include <linux/sched/signal.h>
17 
18 #include "br_private.h"
19 #include "br_private_mcast_eht.h"
20 
21 struct brport_attribute {
22 	struct attribute	attr;
23 	ssize_t (*show)(struct net_bridge_port *, char *);
24 	int (*store)(struct net_bridge_port *, unsigned long);
25 	int (*store_raw)(struct net_bridge_port *, char *);
26 };
27 
28 #define BRPORT_ATTR_RAW(_name, _mode, _show, _store)			\
29 const struct brport_attribute brport_attr_##_name = {			\
30 	.attr		= {.name = __stringify(_name),			\
31 			   .mode = _mode },				\
32 	.show		= _show,					\
33 	.store_raw	= _store,					\
34 };
35 
36 #define BRPORT_ATTR(_name, _mode, _show, _store)		\
37 const struct brport_attribute brport_attr_##_name = { 	        \
38 	.attr = {.name = __stringify(_name), 			\
39 		 .mode = _mode },				\
40 	.show	= _show,					\
41 	.store	= _store,					\
42 };
43 
44 #define BRPORT_ATTR_FLAG(_name, _mask)				\
45 static ssize_t show_##_name(struct net_bridge_port *p, char *buf) \
46 {								\
47 	return sprintf(buf, "%d\n", !!(p->flags & _mask));	\
48 }								\
49 static int store_##_name(struct net_bridge_port *p, unsigned long v) \
50 {								\
51 	return store_flag(p, v, _mask);				\
52 }								\
53 static BRPORT_ATTR(_name, 0644,					\
54 		   show_##_name, store_##_name)
55 
56 static int store_flag(struct net_bridge_port *p, unsigned long v,
57 		      unsigned long mask)
58 {
59 	unsigned long flags;
60 
61 	flags = p->flags;
62 
63 	if (v)
64 		flags |= mask;
65 	else
66 		flags &= ~mask;
67 
68 	if (flags != p->flags) {
69 		p->flags = flags;
70 		br_port_flags_change(p, mask);
71 	}
72 	return 0;
73 }
74 
75 static ssize_t show_path_cost(struct net_bridge_port *p, char *buf)
76 {
77 	return sprintf(buf, "%d\n", p->path_cost);
78 }
79 
80 static BRPORT_ATTR(path_cost, 0644,
81 		   show_path_cost, br_stp_set_path_cost);
82 
83 static ssize_t show_priority(struct net_bridge_port *p, char *buf)
84 {
85 	return sprintf(buf, "%d\n", p->priority);
86 }
87 
88 static BRPORT_ATTR(priority, 0644,
89 			 show_priority, br_stp_set_port_priority);
90 
91 static ssize_t show_designated_root(struct net_bridge_port *p, char *buf)
92 {
93 	return br_show_bridge_id(buf, &p->designated_root);
94 }
95 static BRPORT_ATTR(designated_root, 0444, show_designated_root, NULL);
96 
97 static ssize_t show_designated_bridge(struct net_bridge_port *p, char *buf)
98 {
99 	return br_show_bridge_id(buf, &p->designated_bridge);
100 }
101 static BRPORT_ATTR(designated_bridge, 0444, show_designated_bridge, NULL);
102 
103 static ssize_t show_designated_port(struct net_bridge_port *p, char *buf)
104 {
105 	return sprintf(buf, "%d\n", p->designated_port);
106 }
107 static BRPORT_ATTR(designated_port, 0444, show_designated_port, NULL);
108 
109 static ssize_t show_designated_cost(struct net_bridge_port *p, char *buf)
110 {
111 	return sprintf(buf, "%d\n", p->designated_cost);
112 }
113 static BRPORT_ATTR(designated_cost, 0444, show_designated_cost, NULL);
114 
115 static ssize_t show_port_id(struct net_bridge_port *p, char *buf)
116 {
117 	return sprintf(buf, "0x%x\n", p->port_id);
118 }
119 static BRPORT_ATTR(port_id, 0444, show_port_id, NULL);
120 
121 static ssize_t show_port_no(struct net_bridge_port *p, char *buf)
122 {
123 	return sprintf(buf, "0x%x\n", p->port_no);
124 }
125 
126 static BRPORT_ATTR(port_no, 0444, show_port_no, NULL);
127 
128 static ssize_t show_change_ack(struct net_bridge_port *p, char *buf)
129 {
130 	return sprintf(buf, "%d\n", p->topology_change_ack);
131 }
132 static BRPORT_ATTR(change_ack, 0444, show_change_ack, NULL);
133 
134 static ssize_t show_config_pending(struct net_bridge_port *p, char *buf)
135 {
136 	return sprintf(buf, "%d\n", p->config_pending);
137 }
138 static BRPORT_ATTR(config_pending, 0444, show_config_pending, NULL);
139 
140 static ssize_t show_port_state(struct net_bridge_port *p, char *buf)
141 {
142 	return sprintf(buf, "%d\n", p->state);
143 }
144 static BRPORT_ATTR(state, 0444, show_port_state, NULL);
145 
146 static ssize_t show_message_age_timer(struct net_bridge_port *p,
147 					    char *buf)
148 {
149 	return sprintf(buf, "%ld\n", br_timer_value(&p->message_age_timer));
150 }
151 static BRPORT_ATTR(message_age_timer, 0444, show_message_age_timer, NULL);
152 
153 static ssize_t show_forward_delay_timer(struct net_bridge_port *p,
154 					    char *buf)
155 {
156 	return sprintf(buf, "%ld\n", br_timer_value(&p->forward_delay_timer));
157 }
158 static BRPORT_ATTR(forward_delay_timer, 0444, show_forward_delay_timer, NULL);
159 
160 static ssize_t show_hold_timer(struct net_bridge_port *p,
161 					    char *buf)
162 {
163 	return sprintf(buf, "%ld\n", br_timer_value(&p->hold_timer));
164 }
165 static BRPORT_ATTR(hold_timer, 0444, show_hold_timer, NULL);
166 
167 static int store_flush(struct net_bridge_port *p, unsigned long v)
168 {
169 	br_fdb_delete_by_port(p->br, p, 0, 0); // Don't delete local entry
170 	return 0;
171 }
172 static BRPORT_ATTR(flush, 0200, NULL, store_flush);
173 
174 static ssize_t show_group_fwd_mask(struct net_bridge_port *p, char *buf)
175 {
176 	return sprintf(buf, "%#x\n", p->group_fwd_mask);
177 }
178 
179 static int store_group_fwd_mask(struct net_bridge_port *p,
180 				unsigned long v)
181 {
182 	if (v & BR_GROUPFWD_MACPAUSE)
183 		return -EINVAL;
184 	p->group_fwd_mask = v;
185 
186 	return 0;
187 }
188 static BRPORT_ATTR(group_fwd_mask, 0644, show_group_fwd_mask,
189 		   store_group_fwd_mask);
190 
191 static ssize_t show_backup_port(struct net_bridge_port *p, char *buf)
192 {
193 	struct net_bridge_port *backup_p;
194 	int ret = 0;
195 
196 	rcu_read_lock();
197 	backup_p = rcu_dereference(p->backup_port);
198 	if (backup_p)
199 		ret = sprintf(buf, "%s\n", backup_p->dev->name);
200 	rcu_read_unlock();
201 
202 	return ret;
203 }
204 
205 static int store_backup_port(struct net_bridge_port *p, char *buf)
206 {
207 	struct net_device *backup_dev = NULL;
208 	char *nl = strchr(buf, '\n');
209 
210 	if (nl)
211 		*nl = '\0';
212 
213 	if (strlen(buf) > 0) {
214 		backup_dev = __dev_get_by_name(dev_net(p->dev), buf);
215 		if (!backup_dev)
216 			return -ENOENT;
217 	}
218 
219 	return nbp_backup_change(p, backup_dev);
220 }
221 static BRPORT_ATTR_RAW(backup_port, 0644, show_backup_port, store_backup_port);
222 
223 BRPORT_ATTR_FLAG(hairpin_mode, BR_HAIRPIN_MODE);
224 BRPORT_ATTR_FLAG(bpdu_guard, BR_BPDU_GUARD);
225 BRPORT_ATTR_FLAG(root_block, BR_ROOT_BLOCK);
226 BRPORT_ATTR_FLAG(learning, BR_LEARNING);
227 BRPORT_ATTR_FLAG(unicast_flood, BR_FLOOD);
228 BRPORT_ATTR_FLAG(proxyarp, BR_PROXYARP);
229 BRPORT_ATTR_FLAG(proxyarp_wifi, BR_PROXYARP_WIFI);
230 BRPORT_ATTR_FLAG(multicast_flood, BR_MCAST_FLOOD);
231 BRPORT_ATTR_FLAG(broadcast_flood, BR_BCAST_FLOOD);
232 BRPORT_ATTR_FLAG(neigh_suppress, BR_NEIGH_SUPPRESS);
233 BRPORT_ATTR_FLAG(isolated, BR_ISOLATED);
234 
235 #ifdef CONFIG_BRIDGE_IGMP_SNOOPING
236 static ssize_t show_multicast_router(struct net_bridge_port *p, char *buf)
237 {
238 	return sprintf(buf, "%d\n", p->multicast_router);
239 }
240 
241 static int store_multicast_router(struct net_bridge_port *p,
242 				      unsigned long v)
243 {
244 	return br_multicast_set_port_router(p, v);
245 }
246 static BRPORT_ATTR(multicast_router, 0644, show_multicast_router,
247 		   store_multicast_router);
248 
249 static ssize_t show_multicast_eht_hosts_limit(struct net_bridge_port *p,
250 					      char *buf)
251 {
252 	return sprintf(buf, "%u\n", p->multicast_eht_hosts_limit);
253 }
254 
255 static int store_multicast_eht_hosts_limit(struct net_bridge_port *p,
256 					   unsigned long v)
257 {
258 	return br_multicast_eht_set_hosts_limit(p, v);
259 }
260 static BRPORT_ATTR(multicast_eht_hosts_limit, 0644,
261 		   show_multicast_eht_hosts_limit,
262 		   store_multicast_eht_hosts_limit);
263 
264 static ssize_t show_multicast_eht_hosts_cnt(struct net_bridge_port *p,
265 					    char *buf)
266 {
267 	return sprintf(buf, "%u\n", p->multicast_eht_hosts_cnt);
268 }
269 static BRPORT_ATTR(multicast_eht_hosts_cnt, 0444, show_multicast_eht_hosts_cnt,
270 		   NULL);
271 
272 BRPORT_ATTR_FLAG(multicast_fast_leave, BR_MULTICAST_FAST_LEAVE);
273 BRPORT_ATTR_FLAG(multicast_to_unicast, BR_MULTICAST_TO_UNICAST);
274 #endif
275 
276 static const struct brport_attribute *brport_attrs[] = {
277 	&brport_attr_path_cost,
278 	&brport_attr_priority,
279 	&brport_attr_port_id,
280 	&brport_attr_port_no,
281 	&brport_attr_designated_root,
282 	&brport_attr_designated_bridge,
283 	&brport_attr_designated_port,
284 	&brport_attr_designated_cost,
285 	&brport_attr_state,
286 	&brport_attr_change_ack,
287 	&brport_attr_config_pending,
288 	&brport_attr_message_age_timer,
289 	&brport_attr_forward_delay_timer,
290 	&brport_attr_hold_timer,
291 	&brport_attr_flush,
292 	&brport_attr_hairpin_mode,
293 	&brport_attr_bpdu_guard,
294 	&brport_attr_root_block,
295 	&brport_attr_learning,
296 	&brport_attr_unicast_flood,
297 #ifdef CONFIG_BRIDGE_IGMP_SNOOPING
298 	&brport_attr_multicast_router,
299 	&brport_attr_multicast_fast_leave,
300 	&brport_attr_multicast_to_unicast,
301 	&brport_attr_multicast_eht_hosts_limit,
302 	&brport_attr_multicast_eht_hosts_cnt,
303 #endif
304 	&brport_attr_proxyarp,
305 	&brport_attr_proxyarp_wifi,
306 	&brport_attr_multicast_flood,
307 	&brport_attr_broadcast_flood,
308 	&brport_attr_group_fwd_mask,
309 	&brport_attr_neigh_suppress,
310 	&brport_attr_isolated,
311 	&brport_attr_backup_port,
312 	NULL
313 };
314 
315 #define to_brport_attr(_at) container_of(_at, struct brport_attribute, attr)
316 
317 static ssize_t brport_show(struct kobject *kobj,
318 			   struct attribute *attr, char *buf)
319 {
320 	struct brport_attribute *brport_attr = to_brport_attr(attr);
321 	struct net_bridge_port *p = kobj_to_brport(kobj);
322 
323 	if (!brport_attr->show)
324 		return -EINVAL;
325 
326 	return brport_attr->show(p, buf);
327 }
328 
329 static ssize_t brport_store(struct kobject *kobj,
330 			    struct attribute *attr,
331 			    const char *buf, size_t count)
332 {
333 	struct brport_attribute *brport_attr = to_brport_attr(attr);
334 	struct net_bridge_port *p = kobj_to_brport(kobj);
335 	ssize_t ret = -EINVAL;
336 	unsigned long val;
337 	char *endp;
338 
339 	if (!ns_capable(dev_net(p->dev)->user_ns, CAP_NET_ADMIN))
340 		return -EPERM;
341 
342 	if (!rtnl_trylock())
343 		return restart_syscall();
344 
345 	if (brport_attr->store_raw) {
346 		char *buf_copy;
347 
348 		buf_copy = kstrndup(buf, count, GFP_KERNEL);
349 		if (!buf_copy) {
350 			ret = -ENOMEM;
351 			goto out_unlock;
352 		}
353 		spin_lock_bh(&p->br->lock);
354 		ret = brport_attr->store_raw(p, buf_copy);
355 		spin_unlock_bh(&p->br->lock);
356 		kfree(buf_copy);
357 	} else if (brport_attr->store) {
358 		val = simple_strtoul(buf, &endp, 0);
359 		if (endp == buf)
360 			goto out_unlock;
361 		spin_lock_bh(&p->br->lock);
362 		ret = brport_attr->store(p, val);
363 		spin_unlock_bh(&p->br->lock);
364 	}
365 
366 	if (!ret) {
367 		br_ifinfo_notify(RTM_NEWLINK, NULL, p);
368 		ret = count;
369 	}
370 out_unlock:
371 	rtnl_unlock();
372 
373 	return ret;
374 }
375 
376 const struct sysfs_ops brport_sysfs_ops = {
377 	.show = brport_show,
378 	.store = brport_store,
379 };
380 
381 /*
382  * Add sysfs entries to ethernet device added to a bridge.
383  * Creates a brport subdirectory with bridge attributes.
384  * Puts symlink in bridge's brif subdirectory
385  */
386 int br_sysfs_addif(struct net_bridge_port *p)
387 {
388 	struct net_bridge *br = p->br;
389 	const struct brport_attribute **a;
390 	int err;
391 
392 	err = sysfs_create_link(&p->kobj, &br->dev->dev.kobj,
393 				SYSFS_BRIDGE_PORT_LINK);
394 	if (err)
395 		return err;
396 
397 	for (a = brport_attrs; *a; ++a) {
398 		err = sysfs_create_file(&p->kobj, &((*a)->attr));
399 		if (err)
400 			return err;
401 	}
402 
403 	strlcpy(p->sysfs_name, p->dev->name, IFNAMSIZ);
404 	return sysfs_create_link(br->ifobj, &p->kobj, p->sysfs_name);
405 }
406 
407 /* Rename bridge's brif symlink */
408 int br_sysfs_renameif(struct net_bridge_port *p)
409 {
410 	struct net_bridge *br = p->br;
411 	int err;
412 
413 	/* If a rename fails, the rollback will cause another
414 	 * rename call with the existing name.
415 	 */
416 	if (!strncmp(p->sysfs_name, p->dev->name, IFNAMSIZ))
417 		return 0;
418 
419 	err = sysfs_rename_link(br->ifobj, &p->kobj,
420 				p->sysfs_name, p->dev->name);
421 	if (err)
422 		netdev_notice(br->dev, "unable to rename link %s to %s",
423 			      p->sysfs_name, p->dev->name);
424 	else
425 		strlcpy(p->sysfs_name, p->dev->name, IFNAMSIZ);
426 
427 	return err;
428 }
429