Blame view

net/bridge/br_sysfs_br.c 25.7 KB
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1
  /*
15401946f   Wang Sheng-Hui   bridge: correct t...
2
   *	Sysfs attributes of bridge
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3
4
5
6
7
8
9
10
11
12
   *	Linux ethernet bridge
   *
   *	Authors:
   *	Stephen Hemminger		<shemminger@osdl.org>
   *
   *	This program is free software; you can redistribute it and/or
   *	modify it under the terms of the GNU General Public License
   *	as published by the Free Software Foundation; either version
   *	2 of the License, or (at your option) any later version.
   */
4fc268d24   Randy Dunlap   [PATCH] capable/c...
13
  #include <linux/capability.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
14
15
  #include <linux/kernel.h>
  #include <linux/netdevice.h>
b3343a2a2   John Fastabend   net, ixgbe: handl...
16
  #include <linux/etherdevice.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
17
18
19
20
  #include <linux/if_bridge.h>
  #include <linux/rtnetlink.h>
  #include <linux/spinlock.h>
  #include <linux/times.h>
174cd4b1e   Ingo Molnar   sched/headers: Pr...
21
  #include <linux/sched/signal.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
22
23
  
  #include "br_private.h"
524ad0a79   Wang Chen   netdevice: safe c...
24
  #define to_bridge(cd)	((struct net_bridge *)netdev_priv(to_net_dev(cd)))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
25
26
27
28
  
  /*
   * Common code for storing bridge parameters.
   */
43cb76d91   Greg Kroah-Hartman   Network: convert ...
29
  static ssize_t store_bridge_parm(struct device *d,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
30
  				 const char *buf, size_t len,
8d4698f7a   Stephen Hemminger   bridge: don't all...
31
  				 int (*set)(struct net_bridge *, unsigned long))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
32
  {
43cb76d91   Greg Kroah-Hartman   Network: convert ...
33
  	struct net_bridge *br = to_bridge(d);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
34
35
  	char *endp;
  	unsigned long val;
8d4698f7a   Stephen Hemminger   bridge: don't all...
36
  	int err;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
37

cb9905030   Eric W. Biederman   net: Allow userns...
38
  	if (!ns_capable(dev_net(br->dev)->user_ns, CAP_NET_ADMIN))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
39
40
41
42
43
  		return -EPERM;
  
  	val = simple_strtoul(buf, &endp, 0);
  	if (endp == buf)
  		return -EINVAL;
047831a9b   Xin Long   bridge: a netlink...
44
45
  	if (!rtnl_trylock())
  		return restart_syscall();
8d4698f7a   Stephen Hemminger   bridge: don't all...
46
  	err = (*set)(br, val);
047831a9b   Xin Long   bridge: a netlink...
47
48
49
  	if (!err)
  		netdev_state_change(br->dev);
  	rtnl_unlock();
8d4698f7a   Stephen Hemminger   bridge: don't all...
50
  	return err ? err : len;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
51
  }
fbf2671bb   sfeldma@cumulusnetworks.com   bridge: use DEVIC...
52
  static ssize_t forward_delay_show(struct device *d,
43cb76d91   Greg Kroah-Hartman   Network: convert ...
53
  				  struct device_attribute *attr, char *buf)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
54
  {
43cb76d91   Greg Kroah-Hartman   Network: convert ...
55
  	struct net_bridge *br = to_bridge(d);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
56
57
58
  	return sprintf(buf, "%lu
  ", jiffies_to_clock_t(br->forward_delay));
  }
fbf2671bb   sfeldma@cumulusnetworks.com   bridge: use DEVIC...
59
  static ssize_t forward_delay_store(struct device *d,
43cb76d91   Greg Kroah-Hartman   Network: convert ...
60
61
  				   struct device_attribute *attr,
  				   const char *buf, size_t len)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
62
  {
14f98f258   stephen hemminger   bridge: range che...
63
  	return store_bridge_parm(d, buf, len, br_set_forward_delay);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
64
  }
fbf2671bb   sfeldma@cumulusnetworks.com   bridge: use DEVIC...
65
  static DEVICE_ATTR_RW(forward_delay);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
66

fbf2671bb   sfeldma@cumulusnetworks.com   bridge: use DEVIC...
67
  static ssize_t hello_time_show(struct device *d, struct device_attribute *attr,
43cb76d91   Greg Kroah-Hartman   Network: convert ...
68
  			       char *buf)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
69
70
71
  {
  	return sprintf(buf, "%lu
  ",
43cb76d91   Greg Kroah-Hartman   Network: convert ...
72
  		       jiffies_to_clock_t(to_bridge(d)->hello_time));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
73
  }
fbf2671bb   sfeldma@cumulusnetworks.com   bridge: use DEVIC...
74
  static ssize_t hello_time_store(struct device *d,
43cb76d91   Greg Kroah-Hartman   Network: convert ...
75
  				struct device_attribute *attr, const char *buf,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
76
77
  				size_t len)
  {
14f98f258   stephen hemminger   bridge: range che...
78
  	return store_bridge_parm(d, buf, len, br_set_hello_time);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
79
  }
fbf2671bb   sfeldma@cumulusnetworks.com   bridge: use DEVIC...
80
  static DEVICE_ATTR_RW(hello_time);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
81

fbf2671bb   sfeldma@cumulusnetworks.com   bridge: use DEVIC...
82
  static ssize_t max_age_show(struct device *d, struct device_attribute *attr,
43cb76d91   Greg Kroah-Hartman   Network: convert ...
83
  			    char *buf)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
84
85
86
  {
  	return sprintf(buf, "%lu
  ",
43cb76d91   Greg Kroah-Hartman   Network: convert ...
87
  		       jiffies_to_clock_t(to_bridge(d)->max_age));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
88
  }
fbf2671bb   sfeldma@cumulusnetworks.com   bridge: use DEVIC...
89
  static ssize_t max_age_store(struct device *d, struct device_attribute *attr,
43cb76d91   Greg Kroah-Hartman   Network: convert ...
90
  			     const char *buf, size_t len)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
91
  {
14f98f258   stephen hemminger   bridge: range che...
92
  	return store_bridge_parm(d, buf, len, br_set_max_age);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
93
  }
fbf2671bb   sfeldma@cumulusnetworks.com   bridge: use DEVIC...
94
  static DEVICE_ATTR_RW(max_age);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
95

fbf2671bb   sfeldma@cumulusnetworks.com   bridge: use DEVIC...
96
  static ssize_t ageing_time_show(struct device *d,
43cb76d91   Greg Kroah-Hartman   Network: convert ...
97
  				struct device_attribute *attr, char *buf)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
98
  {
43cb76d91   Greg Kroah-Hartman   Network: convert ...
99
  	struct net_bridge *br = to_bridge(d);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
100
101
102
  	return sprintf(buf, "%lu
  ", jiffies_to_clock_t(br->ageing_time));
  }
8d4698f7a   Stephen Hemminger   bridge: don't all...
103
  static int set_ageing_time(struct net_bridge *br, unsigned long val)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
104
  {
047831a9b   Xin Long   bridge: a netlink...
105
  	return br_set_ageing_time(br, val);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
106
  }
fbf2671bb   sfeldma@cumulusnetworks.com   bridge: use DEVIC...
107
  static ssize_t ageing_time_store(struct device *d,
43cb76d91   Greg Kroah-Hartman   Network: convert ...
108
109
  				 struct device_attribute *attr,
  				 const char *buf, size_t len)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
110
  {
43cb76d91   Greg Kroah-Hartman   Network: convert ...
111
  	return store_bridge_parm(d, buf, len, set_ageing_time);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
112
  }
fbf2671bb   sfeldma@cumulusnetworks.com   bridge: use DEVIC...
113
  static DEVICE_ATTR_RW(ageing_time);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
114

fbf2671bb   sfeldma@cumulusnetworks.com   bridge: use DEVIC...
115
  static ssize_t stp_state_show(struct device *d,
43cb76d91   Greg Kroah-Hartman   Network: convert ...
116
  			      struct device_attribute *attr, char *buf)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
117
  {
43cb76d91   Greg Kroah-Hartman   Network: convert ...
118
  	struct net_bridge *br = to_bridge(d);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
119
120
121
  	return sprintf(buf, "%d
  ", br->stp_enabled);
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
122

4436156b6   Xin Long   bridge: simplify ...
123
  static int set_stp_state(struct net_bridge *br, unsigned long val)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
124
  {
17120889b   Stephen Hemminger   [BRIDGE]: sysfs l...
125
  	br_stp_set_enabled(br, val);
17120889b   Stephen Hemminger   [BRIDGE]: sysfs l...
126

4436156b6   Xin Long   bridge: simplify ...
127
128
129
130
131
132
133
134
  	return 0;
  }
  
  static ssize_t stp_state_store(struct device *d,
  			       struct device_attribute *attr, const char *buf,
  			       size_t len)
  {
  	return store_bridge_parm(d, buf, len, set_stp_state);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
135
  }
fbf2671bb   sfeldma@cumulusnetworks.com   bridge: use DEVIC...
136
  static DEVICE_ATTR_RW(stp_state);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
137

fbf2671bb   sfeldma@cumulusnetworks.com   bridge: use DEVIC...
138
139
140
  static ssize_t group_fwd_mask_show(struct device *d,
  				   struct device_attribute *attr,
  				   char *buf)
515853cce   stephen hemminger   bridge: allow for...
141
142
143
144
145
  {
  	struct net_bridge *br = to_bridge(d);
  	return sprintf(buf, "%#x
  ", br->group_fwd_mask);
  }
347db6b49   Xin Long   bridge: simplify ...
146
  static int set_group_fwd_mask(struct net_bridge *br, unsigned long val)
515853cce   stephen hemminger   bridge: allow for...
147
  {
515853cce   stephen hemminger   bridge: allow for...
148
149
150
151
  	if (val & BR_GROUPFWD_RESTRICTED)
  		return -EINVAL;
  
  	br->group_fwd_mask = val;
347db6b49   Xin Long   bridge: simplify ...
152
153
154
155
156
157
158
159
160
  	return 0;
  }
  
  static ssize_t group_fwd_mask_store(struct device *d,
  				    struct device_attribute *attr,
  				    const char *buf,
  				    size_t len)
  {
  	return store_bridge_parm(d, buf, len, set_group_fwd_mask);
515853cce   stephen hemminger   bridge: allow for...
161
  }
fbf2671bb   sfeldma@cumulusnetworks.com   bridge: use DEVIC...
162
  static DEVICE_ATTR_RW(group_fwd_mask);
515853cce   stephen hemminger   bridge: allow for...
163

fbf2671bb   sfeldma@cumulusnetworks.com   bridge: use DEVIC...
164
  static ssize_t priority_show(struct device *d, struct device_attribute *attr,
43cb76d91   Greg Kroah-Hartman   Network: convert ...
165
  			     char *buf)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
166
  {
43cb76d91   Greg Kroah-Hartman   Network: convert ...
167
  	struct net_bridge *br = to_bridge(d);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
168
169
170
171
  	return sprintf(buf, "%d
  ",
  		       (br->bridge_id.prio[0] << 8) | br->bridge_id.prio[1]);
  }
8d4698f7a   Stephen Hemminger   bridge: don't all...
172
  static int set_priority(struct net_bridge *br, unsigned long val)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
173
174
  {
  	br_stp_set_bridge_priority(br, (u16) val);
8d4698f7a   Stephen Hemminger   bridge: don't all...
175
  	return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
176
  }
fbf2671bb   sfeldma@cumulusnetworks.com   bridge: use DEVIC...
177
178
  static ssize_t priority_store(struct device *d, struct device_attribute *attr,
  			      const char *buf, size_t len)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
179
  {
43cb76d91   Greg Kroah-Hartman   Network: convert ...
180
  	return store_bridge_parm(d, buf, len, set_priority);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
181
  }
fbf2671bb   sfeldma@cumulusnetworks.com   bridge: use DEVIC...
182
  static DEVICE_ATTR_RW(priority);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
183

fbf2671bb   sfeldma@cumulusnetworks.com   bridge: use DEVIC...
184
  static ssize_t root_id_show(struct device *d, struct device_attribute *attr,
43cb76d91   Greg Kroah-Hartman   Network: convert ...
185
  			    char *buf)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
186
  {
43cb76d91   Greg Kroah-Hartman   Network: convert ...
187
  	return br_show_bridge_id(buf, &to_bridge(d)->designated_root);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
188
  }
fbf2671bb   sfeldma@cumulusnetworks.com   bridge: use DEVIC...
189
  static DEVICE_ATTR_RO(root_id);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
190

fbf2671bb   sfeldma@cumulusnetworks.com   bridge: use DEVIC...
191
  static ssize_t bridge_id_show(struct device *d, struct device_attribute *attr,
43cb76d91   Greg Kroah-Hartman   Network: convert ...
192
  			      char *buf)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
193
  {
43cb76d91   Greg Kroah-Hartman   Network: convert ...
194
  	return br_show_bridge_id(buf, &to_bridge(d)->bridge_id);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
195
  }
fbf2671bb   sfeldma@cumulusnetworks.com   bridge: use DEVIC...
196
  static DEVICE_ATTR_RO(bridge_id);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
197

fbf2671bb   sfeldma@cumulusnetworks.com   bridge: use DEVIC...
198
  static ssize_t root_port_show(struct device *d, struct device_attribute *attr,
43cb76d91   Greg Kroah-Hartman   Network: convert ...
199
  			      char *buf)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
200
  {
43cb76d91   Greg Kroah-Hartman   Network: convert ...
201
202
  	return sprintf(buf, "%d
  ", to_bridge(d)->root_port);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
203
  }
fbf2671bb   sfeldma@cumulusnetworks.com   bridge: use DEVIC...
204
  static DEVICE_ATTR_RO(root_port);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
205

fbf2671bb   sfeldma@cumulusnetworks.com   bridge: use DEVIC...
206
  static ssize_t root_path_cost_show(struct device *d,
43cb76d91   Greg Kroah-Hartman   Network: convert ...
207
  				   struct device_attribute *attr, char *buf)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
208
  {
43cb76d91   Greg Kroah-Hartman   Network: convert ...
209
210
  	return sprintf(buf, "%d
  ", to_bridge(d)->root_path_cost);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
211
  }
fbf2671bb   sfeldma@cumulusnetworks.com   bridge: use DEVIC...
212
  static DEVICE_ATTR_RO(root_path_cost);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
213

fbf2671bb   sfeldma@cumulusnetworks.com   bridge: use DEVIC...
214
  static ssize_t topology_change_show(struct device *d,
43cb76d91   Greg Kroah-Hartman   Network: convert ...
215
  				    struct device_attribute *attr, char *buf)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
216
  {
43cb76d91   Greg Kroah-Hartman   Network: convert ...
217
218
  	return sprintf(buf, "%d
  ", to_bridge(d)->topology_change);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
219
  }
fbf2671bb   sfeldma@cumulusnetworks.com   bridge: use DEVIC...
220
  static DEVICE_ATTR_RO(topology_change);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
221

fbf2671bb   sfeldma@cumulusnetworks.com   bridge: use DEVIC...
222
  static ssize_t topology_change_detected_show(struct device *d,
43cb76d91   Greg Kroah-Hartman   Network: convert ...
223
224
  					     struct device_attribute *attr,
  					     char *buf)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
225
  {
43cb76d91   Greg Kroah-Hartman   Network: convert ...
226
  	struct net_bridge *br = to_bridge(d);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
227
228
229
  	return sprintf(buf, "%d
  ", br->topology_change_detected);
  }
fbf2671bb   sfeldma@cumulusnetworks.com   bridge: use DEVIC...
230
  static DEVICE_ATTR_RO(topology_change_detected);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
231

fbf2671bb   sfeldma@cumulusnetworks.com   bridge: use DEVIC...
232
  static ssize_t hello_timer_show(struct device *d,
43cb76d91   Greg Kroah-Hartman   Network: convert ...
233
  				struct device_attribute *attr, char *buf)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
234
  {
43cb76d91   Greg Kroah-Hartman   Network: convert ...
235
  	struct net_bridge *br = to_bridge(d);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
236
237
238
  	return sprintf(buf, "%ld
  ", br_timer_value(&br->hello_timer));
  }
fbf2671bb   sfeldma@cumulusnetworks.com   bridge: use DEVIC...
239
  static DEVICE_ATTR_RO(hello_timer);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
240

fbf2671bb   sfeldma@cumulusnetworks.com   bridge: use DEVIC...
241
  static ssize_t tcn_timer_show(struct device *d, struct device_attribute *attr,
43cb76d91   Greg Kroah-Hartman   Network: convert ...
242
  			      char *buf)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
243
  {
43cb76d91   Greg Kroah-Hartman   Network: convert ...
244
  	struct net_bridge *br = to_bridge(d);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
245
246
247
  	return sprintf(buf, "%ld
  ", br_timer_value(&br->tcn_timer));
  }
fbf2671bb   sfeldma@cumulusnetworks.com   bridge: use DEVIC...
248
  static DEVICE_ATTR_RO(tcn_timer);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
249

fbf2671bb   sfeldma@cumulusnetworks.com   bridge: use DEVIC...
250
  static ssize_t topology_change_timer_show(struct device *d,
43cb76d91   Greg Kroah-Hartman   Network: convert ...
251
252
  					  struct device_attribute *attr,
  					  char *buf)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
253
  {
43cb76d91   Greg Kroah-Hartman   Network: convert ...
254
  	struct net_bridge *br = to_bridge(d);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
255
256
257
  	return sprintf(buf, "%ld
  ", br_timer_value(&br->topology_change_timer));
  }
fbf2671bb   sfeldma@cumulusnetworks.com   bridge: use DEVIC...
258
  static DEVICE_ATTR_RO(topology_change_timer);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
259

fbf2671bb   sfeldma@cumulusnetworks.com   bridge: use DEVIC...
260
  static ssize_t gc_timer_show(struct device *d, struct device_attribute *attr,
43cb76d91   Greg Kroah-Hartman   Network: convert ...
261
  			     char *buf)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
262
  {
43cb76d91   Greg Kroah-Hartman   Network: convert ...
263
  	struct net_bridge *br = to_bridge(d);
f7cdee8a7   Nikolay Aleksandrov   bridge: move to w...
264
265
  	return sprintf(buf, "%ld
  ", br_timer_value(&br->gc_work.timer));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
266
  }
fbf2671bb   sfeldma@cumulusnetworks.com   bridge: use DEVIC...
267
  static DEVICE_ATTR_RO(gc_timer);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
268

fbf2671bb   sfeldma@cumulusnetworks.com   bridge: use DEVIC...
269
  static ssize_t group_addr_show(struct device *d,
43cb76d91   Greg Kroah-Hartman   Network: convert ...
270
  			       struct device_attribute *attr, char *buf)
fda93d92d   Stephen Hemminger   [BRIDGE]: allow s...
271
  {
43cb76d91   Greg Kroah-Hartman   Network: convert ...
272
  	struct net_bridge *br = to_bridge(d);
fda93d92d   Stephen Hemminger   [BRIDGE]: allow s...
273
274
275
276
277
278
  	return sprintf(buf, "%x:%x:%x:%x:%x:%x
  ",
  		       br->group_addr[0], br->group_addr[1],
  		       br->group_addr[2], br->group_addr[3],
  		       br->group_addr[4], br->group_addr[5]);
  }
fbf2671bb   sfeldma@cumulusnetworks.com   bridge: use DEVIC...
279
  static ssize_t group_addr_store(struct device *d,
43cb76d91   Greg Kroah-Hartman   Network: convert ...
280
281
  				struct device_attribute *attr,
  				const char *buf, size_t len)
fda93d92d   Stephen Hemminger   [BRIDGE]: allow s...
282
  {
43cb76d91   Greg Kroah-Hartman   Network: convert ...
283
  	struct net_bridge *br = to_bridge(d);
4197f24b5   Ben Hutchings   bridge: Use is_li...
284
  	u8 new_addr[6];
fda93d92d   Stephen Hemminger   [BRIDGE]: allow s...
285
  	int i;
cb9905030   Eric W. Biederman   net: Allow userns...
286
  	if (!ns_capable(dev_net(br->dev)->user_ns, CAP_NET_ADMIN))
fda93d92d   Stephen Hemminger   [BRIDGE]: allow s...
287
  		return -EPERM;
4197f24b5   Ben Hutchings   bridge: Use is_li...
288
  	if (sscanf(buf, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx",
fda93d92d   Stephen Hemminger   [BRIDGE]: allow s...
289
290
291
  		   &new_addr[0], &new_addr[1], &new_addr[2],
  		   &new_addr[3], &new_addr[4], &new_addr[5]) != 6)
  		return -EINVAL;
46acc460c   Ben Hutchings   eth: Make is_link...
292
  	if (!is_link_local_ether_addr(new_addr))
fda93d92d   Stephen Hemminger   [BRIDGE]: allow s...
293
  		return -EINVAL;
f64f9e719   Joe Perches   net: Move && and ...
294
295
296
  	if (new_addr[5] == 1 ||		/* 802.3x Pause address */
  	    new_addr[5] == 2 ||		/* 802.3ad Slow protocols */
  	    new_addr[5] == 3)		/* 802.1X PAE address */
fda93d92d   Stephen Hemminger   [BRIDGE]: allow s...
297
  		return -EINVAL;
204177f3f   Toshiaki Makita   bridge: Support 8...
298
299
  	if (!rtnl_trylock())
  		return restart_syscall();
fda93d92d   Stephen Hemminger   [BRIDGE]: allow s...
300
301
302
303
  	spin_lock_bh(&br->lock);
  	for (i = 0; i < 6; i++)
  		br->group_addr[i] = new_addr[i];
  	spin_unlock_bh(&br->lock);
204177f3f   Toshiaki Makita   bridge: Support 8...
304
305
306
  
  	br->group_addr_set = true;
  	br_recalculate_fwd_mask(br);
047831a9b   Xin Long   bridge: a netlink...
307
  	netdev_state_change(br->dev);
204177f3f   Toshiaki Makita   bridge: Support 8...
308
309
  
  	rtnl_unlock();
fda93d92d   Stephen Hemminger   [BRIDGE]: allow s...
310
311
  	return len;
  }
fbf2671bb   sfeldma@cumulusnetworks.com   bridge: use DEVIC...
312
  static DEVICE_ATTR_RW(group_addr);
fda93d92d   Stephen Hemminger   [BRIDGE]: allow s...
313

14f31bb39   Xin Long   bridge: simplify ...
314
315
316
317
318
  static int set_flush(struct net_bridge *br, unsigned long val)
  {
  	br_fdb_flush(br);
  	return 0;
  }
fbf2671bb   sfeldma@cumulusnetworks.com   bridge: use DEVIC...
319
  static ssize_t flush_store(struct device *d,
9cf637473   Stephen Hemminger   bridge: add sysfs...
320
321
322
  			   struct device_attribute *attr,
  			   const char *buf, size_t len)
  {
14f31bb39   Xin Long   bridge: simplify ...
323
  	return store_bridge_parm(d, buf, len, set_flush);
9cf637473   Stephen Hemminger   bridge: add sysfs...
324
  }
fbf2671bb   sfeldma@cumulusnetworks.com   bridge: use DEVIC...
325
  static DEVICE_ATTR_WO(flush);
fda93d92d   Stephen Hemminger   [BRIDGE]: allow s...
326

0909e1175   Herbert Xu   bridge: Add multi...
327
  #ifdef CONFIG_BRIDGE_IGMP_SNOOPING
fbf2671bb   sfeldma@cumulusnetworks.com   bridge: use DEVIC...
328
  static ssize_t multicast_router_show(struct device *d,
0909e1175   Herbert Xu   bridge: Add multi...
329
330
331
332
333
334
  				     struct device_attribute *attr, char *buf)
  {
  	struct net_bridge *br = to_bridge(d);
  	return sprintf(buf, "%d
  ", br->multicast_router);
  }
fbf2671bb   sfeldma@cumulusnetworks.com   bridge: use DEVIC...
335
  static ssize_t multicast_router_store(struct device *d,
0909e1175   Herbert Xu   bridge: Add multi...
336
337
338
339
340
  				      struct device_attribute *attr,
  				      const char *buf, size_t len)
  {
  	return store_bridge_parm(d, buf, len, br_multicast_set_router);
  }
fbf2671bb   sfeldma@cumulusnetworks.com   bridge: use DEVIC...
341
  static DEVICE_ATTR_RW(multicast_router);
561f1103a   Herbert Xu   bridge: Add multi...
342

fbf2671bb   sfeldma@cumulusnetworks.com   bridge: use DEVIC...
343
  static ssize_t multicast_snooping_show(struct device *d,
561f1103a   Herbert Xu   bridge: Add multi...
344
345
346
347
348
349
350
  				       struct device_attribute *attr,
  				       char *buf)
  {
  	struct net_bridge *br = to_bridge(d);
  	return sprintf(buf, "%d
  ", !br->multicast_disabled);
  }
fbf2671bb   sfeldma@cumulusnetworks.com   bridge: use DEVIC...
351
  static ssize_t multicast_snooping_store(struct device *d,
561f1103a   Herbert Xu   bridge: Add multi...
352
353
354
355
356
  					struct device_attribute *attr,
  					const char *buf, size_t len)
  {
  	return store_bridge_parm(d, buf, len, br_multicast_toggle);
  }
fbf2671bb   sfeldma@cumulusnetworks.com   bridge: use DEVIC...
357
  static DEVICE_ATTR_RW(multicast_snooping);
b195167fc   Herbert Xu   bridge: Add hash ...
358

fbf2671bb   sfeldma@cumulusnetworks.com   bridge: use DEVIC...
359
360
361
  static ssize_t multicast_query_use_ifaddr_show(struct device *d,
  					       struct device_attribute *attr,
  					       char *buf)
1c8ad5bfa   Cong Wang   bridge: use the b...
362
363
364
365
366
367
368
369
370
371
372
373
374
  {
  	struct net_bridge *br = to_bridge(d);
  	return sprintf(buf, "%d
  ", br->multicast_query_use_ifaddr);
  }
  
  static int set_query_use_ifaddr(struct net_bridge *br, unsigned long val)
  {
  	br->multicast_query_use_ifaddr = !!val;
  	return 0;
  }
  
  static ssize_t
fbf2671bb   sfeldma@cumulusnetworks.com   bridge: use DEVIC...
375
  multicast_query_use_ifaddr_store(struct device *d,
1c8ad5bfa   Cong Wang   bridge: use the b...
376
377
378
379
380
  				 struct device_attribute *attr,
  				 const char *buf, size_t len)
  {
  	return store_bridge_parm(d, buf, len, set_query_use_ifaddr);
  }
fbf2671bb   sfeldma@cumulusnetworks.com   bridge: use DEVIC...
381
  static DEVICE_ATTR_RW(multicast_query_use_ifaddr);
1c8ad5bfa   Cong Wang   bridge: use the b...
382

fbf2671bb   sfeldma@cumulusnetworks.com   bridge: use DEVIC...
383
  static ssize_t multicast_querier_show(struct device *d,
c5c232605   Herbert Xu   bridge: Add multi...
384
385
386
387
388
389
390
  				      struct device_attribute *attr,
  				      char *buf)
  {
  	struct net_bridge *br = to_bridge(d);
  	return sprintf(buf, "%d
  ", br->multicast_querier);
  }
fbf2671bb   sfeldma@cumulusnetworks.com   bridge: use DEVIC...
391
  static ssize_t multicast_querier_store(struct device *d,
c5c232605   Herbert Xu   bridge: Add multi...
392
393
394
395
396
  				       struct device_attribute *attr,
  				       const char *buf, size_t len)
  {
  	return store_bridge_parm(d, buf, len, br_multicast_set_querier);
  }
fbf2671bb   sfeldma@cumulusnetworks.com   bridge: use DEVIC...
397
  static DEVICE_ATTR_RW(multicast_querier);
c5c232605   Herbert Xu   bridge: Add multi...
398

fbf2671bb   sfeldma@cumulusnetworks.com   bridge: use DEVIC...
399
  static ssize_t hash_elasticity_show(struct device *d,
b195167fc   Herbert Xu   bridge: Add hash ...
400
401
402
403
404
405
406
407
408
409
410
411
  				    struct device_attribute *attr, char *buf)
  {
  	struct net_bridge *br = to_bridge(d);
  	return sprintf(buf, "%u
  ", br->hash_elasticity);
  }
  
  static int set_elasticity(struct net_bridge *br, unsigned long val)
  {
  	br->hash_elasticity = val;
  	return 0;
  }
fbf2671bb   sfeldma@cumulusnetworks.com   bridge: use DEVIC...
412
  static ssize_t hash_elasticity_store(struct device *d,
b195167fc   Herbert Xu   bridge: Add hash ...
413
414
415
416
417
  				     struct device_attribute *attr,
  				     const char *buf, size_t len)
  {
  	return store_bridge_parm(d, buf, len, set_elasticity);
  }
fbf2671bb   sfeldma@cumulusnetworks.com   bridge: use DEVIC...
418
  static DEVICE_ATTR_RW(hash_elasticity);
b195167fc   Herbert Xu   bridge: Add hash ...
419

fbf2671bb   sfeldma@cumulusnetworks.com   bridge: use DEVIC...
420
  static ssize_t hash_max_show(struct device *d, struct device_attribute *attr,
b195167fc   Herbert Xu   bridge: Add hash ...
421
422
423
424
425
426
  			     char *buf)
  {
  	struct net_bridge *br = to_bridge(d);
  	return sprintf(buf, "%u
  ", br->hash_max);
  }
fbf2671bb   sfeldma@cumulusnetworks.com   bridge: use DEVIC...
427
  static ssize_t hash_max_store(struct device *d, struct device_attribute *attr,
b195167fc   Herbert Xu   bridge: Add hash ...
428
429
430
431
  			      const char *buf, size_t len)
  {
  	return store_bridge_parm(d, buf, len, br_multicast_set_hash_max);
  }
fbf2671bb   sfeldma@cumulusnetworks.com   bridge: use DEVIC...
432
  static DEVICE_ATTR_RW(hash_max);
d902eee43   Herbert Xu   bridge: Add multi...
433

5e9235853   Nikolay Aleksandrov   bridge: mcast: ad...
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
  static ssize_t multicast_igmp_version_show(struct device *d,
  					   struct device_attribute *attr,
  					   char *buf)
  {
  	struct net_bridge *br = to_bridge(d);
  
  	return sprintf(buf, "%u
  ", br->multicast_igmp_version);
  }
  
  static ssize_t multicast_igmp_version_store(struct device *d,
  					    struct device_attribute *attr,
  					    const char *buf, size_t len)
  {
  	return store_bridge_parm(d, buf, len, br_multicast_set_igmp_version);
  }
  static DEVICE_ATTR_RW(multicast_igmp_version);
fbf2671bb   sfeldma@cumulusnetworks.com   bridge: use DEVIC...
451
  static ssize_t multicast_last_member_count_show(struct device *d,
d902eee43   Herbert Xu   bridge: Add multi...
452
453
454
455
456
457
458
459
460
461
462
463
464
  						struct device_attribute *attr,
  						char *buf)
  {
  	struct net_bridge *br = to_bridge(d);
  	return sprintf(buf, "%u
  ", br->multicast_last_member_count);
  }
  
  static int set_last_member_count(struct net_bridge *br, unsigned long val)
  {
  	br->multicast_last_member_count = val;
  	return 0;
  }
fbf2671bb   sfeldma@cumulusnetworks.com   bridge: use DEVIC...
465
  static ssize_t multicast_last_member_count_store(struct device *d,
d902eee43   Herbert Xu   bridge: Add multi...
466
467
468
469
470
  						 struct device_attribute *attr,
  						 const char *buf, size_t len)
  {
  	return store_bridge_parm(d, buf, len, set_last_member_count);
  }
fbf2671bb   sfeldma@cumulusnetworks.com   bridge: use DEVIC...
471
  static DEVICE_ATTR_RW(multicast_last_member_count);
d902eee43   Herbert Xu   bridge: Add multi...
472

fbf2671bb   sfeldma@cumulusnetworks.com   bridge: use DEVIC...
473
  static ssize_t multicast_startup_query_count_show(
d902eee43   Herbert Xu   bridge: Add multi...
474
475
476
477
478
479
480
481
482
483
484
485
  	struct device *d, struct device_attribute *attr, char *buf)
  {
  	struct net_bridge *br = to_bridge(d);
  	return sprintf(buf, "%u
  ", br->multicast_startup_query_count);
  }
  
  static int set_startup_query_count(struct net_bridge *br, unsigned long val)
  {
  	br->multicast_startup_query_count = val;
  	return 0;
  }
fbf2671bb   sfeldma@cumulusnetworks.com   bridge: use DEVIC...
486
  static ssize_t multicast_startup_query_count_store(
d902eee43   Herbert Xu   bridge: Add multi...
487
488
489
490
491
  	struct device *d, struct device_attribute *attr, const char *buf,
  	size_t len)
  {
  	return store_bridge_parm(d, buf, len, set_startup_query_count);
  }
fbf2671bb   sfeldma@cumulusnetworks.com   bridge: use DEVIC...
492
  static DEVICE_ATTR_RW(multicast_startup_query_count);
d902eee43   Herbert Xu   bridge: Add multi...
493

fbf2671bb   sfeldma@cumulusnetworks.com   bridge: use DEVIC...
494
  static ssize_t multicast_last_member_interval_show(
d902eee43   Herbert Xu   bridge: Add multi...
495
496
497
498
499
500
501
502
503
504
505
506
507
  	struct device *d, struct device_attribute *attr, char *buf)
  {
  	struct net_bridge *br = to_bridge(d);
  	return sprintf(buf, "%lu
  ",
  		       jiffies_to_clock_t(br->multicast_last_member_interval));
  }
  
  static int set_last_member_interval(struct net_bridge *br, unsigned long val)
  {
  	br->multicast_last_member_interval = clock_t_to_jiffies(val);
  	return 0;
  }
fbf2671bb   sfeldma@cumulusnetworks.com   bridge: use DEVIC...
508
  static ssize_t multicast_last_member_interval_store(
d902eee43   Herbert Xu   bridge: Add multi...
509
510
511
512
513
  	struct device *d, struct device_attribute *attr, const char *buf,
  	size_t len)
  {
  	return store_bridge_parm(d, buf, len, set_last_member_interval);
  }
fbf2671bb   sfeldma@cumulusnetworks.com   bridge: use DEVIC...
514
  static DEVICE_ATTR_RW(multicast_last_member_interval);
d902eee43   Herbert Xu   bridge: Add multi...
515

fbf2671bb   sfeldma@cumulusnetworks.com   bridge: use DEVIC...
516
  static ssize_t multicast_membership_interval_show(
d902eee43   Herbert Xu   bridge: Add multi...
517
518
519
520
521
522
523
524
525
526
527
528
529
  	struct device *d, struct device_attribute *attr, char *buf)
  {
  	struct net_bridge *br = to_bridge(d);
  	return sprintf(buf, "%lu
  ",
  		       jiffies_to_clock_t(br->multicast_membership_interval));
  }
  
  static int set_membership_interval(struct net_bridge *br, unsigned long val)
  {
  	br->multicast_membership_interval = clock_t_to_jiffies(val);
  	return 0;
  }
fbf2671bb   sfeldma@cumulusnetworks.com   bridge: use DEVIC...
530
  static ssize_t multicast_membership_interval_store(
d902eee43   Herbert Xu   bridge: Add multi...
531
532
533
534
535
  	struct device *d, struct device_attribute *attr, const char *buf,
  	size_t len)
  {
  	return store_bridge_parm(d, buf, len, set_membership_interval);
  }
fbf2671bb   sfeldma@cumulusnetworks.com   bridge: use DEVIC...
536
  static DEVICE_ATTR_RW(multicast_membership_interval);
d902eee43   Herbert Xu   bridge: Add multi...
537

fbf2671bb   sfeldma@cumulusnetworks.com   bridge: use DEVIC...
538
  static ssize_t multicast_querier_interval_show(struct device *d,
d902eee43   Herbert Xu   bridge: Add multi...
539
540
541
542
543
544
545
546
547
548
549
550
551
552
  					       struct device_attribute *attr,
  					       char *buf)
  {
  	struct net_bridge *br = to_bridge(d);
  	return sprintf(buf, "%lu
  ",
  		       jiffies_to_clock_t(br->multicast_querier_interval));
  }
  
  static int set_querier_interval(struct net_bridge *br, unsigned long val)
  {
  	br->multicast_querier_interval = clock_t_to_jiffies(val);
  	return 0;
  }
fbf2671bb   sfeldma@cumulusnetworks.com   bridge: use DEVIC...
553
  static ssize_t multicast_querier_interval_store(struct device *d,
d902eee43   Herbert Xu   bridge: Add multi...
554
555
556
557
558
  						struct device_attribute *attr,
  						const char *buf, size_t len)
  {
  	return store_bridge_parm(d, buf, len, set_querier_interval);
  }
fbf2671bb   sfeldma@cumulusnetworks.com   bridge: use DEVIC...
559
  static DEVICE_ATTR_RW(multicast_querier_interval);
d902eee43   Herbert Xu   bridge: Add multi...
560

fbf2671bb   sfeldma@cumulusnetworks.com   bridge: use DEVIC...
561
  static ssize_t multicast_query_interval_show(struct device *d,
d902eee43   Herbert Xu   bridge: Add multi...
562
563
564
565
566
567
568
569
570
571
572
573
574
575
  					     struct device_attribute *attr,
  					     char *buf)
  {
  	struct net_bridge *br = to_bridge(d);
  	return sprintf(buf, "%lu
  ",
  		       jiffies_to_clock_t(br->multicast_query_interval));
  }
  
  static int set_query_interval(struct net_bridge *br, unsigned long val)
  {
  	br->multicast_query_interval = clock_t_to_jiffies(val);
  	return 0;
  }
fbf2671bb   sfeldma@cumulusnetworks.com   bridge: use DEVIC...
576
  static ssize_t multicast_query_interval_store(struct device *d,
d902eee43   Herbert Xu   bridge: Add multi...
577
578
579
580
581
  					      struct device_attribute *attr,
  					      const char *buf, size_t len)
  {
  	return store_bridge_parm(d, buf, len, set_query_interval);
  }
fbf2671bb   sfeldma@cumulusnetworks.com   bridge: use DEVIC...
582
  static DEVICE_ATTR_RW(multicast_query_interval);
d902eee43   Herbert Xu   bridge: Add multi...
583

fbf2671bb   sfeldma@cumulusnetworks.com   bridge: use DEVIC...
584
  static ssize_t multicast_query_response_interval_show(
d902eee43   Herbert Xu   bridge: Add multi...
585
586
587
588
589
590
591
592
593
594
595
596
597
598
  	struct device *d, struct device_attribute *attr, char *buf)
  {
  	struct net_bridge *br = to_bridge(d);
  	return sprintf(
  		buf, "%lu
  ",
  		jiffies_to_clock_t(br->multicast_query_response_interval));
  }
  
  static int set_query_response_interval(struct net_bridge *br, unsigned long val)
  {
  	br->multicast_query_response_interval = clock_t_to_jiffies(val);
  	return 0;
  }
fbf2671bb   sfeldma@cumulusnetworks.com   bridge: use DEVIC...
599
  static ssize_t multicast_query_response_interval_store(
d902eee43   Herbert Xu   bridge: Add multi...
600
601
602
603
604
  	struct device *d, struct device_attribute *attr, const char *buf,
  	size_t len)
  {
  	return store_bridge_parm(d, buf, len, set_query_response_interval);
  }
fbf2671bb   sfeldma@cumulusnetworks.com   bridge: use DEVIC...
605
  static DEVICE_ATTR_RW(multicast_query_response_interval);
d902eee43   Herbert Xu   bridge: Add multi...
606

fbf2671bb   sfeldma@cumulusnetworks.com   bridge: use DEVIC...
607
  static ssize_t multicast_startup_query_interval_show(
d902eee43   Herbert Xu   bridge: Add multi...
608
609
610
611
612
613
614
615
616
617
618
619
620
621
  	struct device *d, struct device_attribute *attr, char *buf)
  {
  	struct net_bridge *br = to_bridge(d);
  	return sprintf(
  		buf, "%lu
  ",
  		jiffies_to_clock_t(br->multicast_startup_query_interval));
  }
  
  static int set_startup_query_interval(struct net_bridge *br, unsigned long val)
  {
  	br->multicast_startup_query_interval = clock_t_to_jiffies(val);
  	return 0;
  }
fbf2671bb   sfeldma@cumulusnetworks.com   bridge: use DEVIC...
622
  static ssize_t multicast_startup_query_interval_store(
d902eee43   Herbert Xu   bridge: Add multi...
623
624
625
626
627
  	struct device *d, struct device_attribute *attr, const char *buf,
  	size_t len)
  {
  	return store_bridge_parm(d, buf, len, set_startup_query_interval);
  }
fbf2671bb   sfeldma@cumulusnetworks.com   bridge: use DEVIC...
628
  static DEVICE_ATTR_RW(multicast_startup_query_interval);
1080ab95e   Nikolay Aleksandrov   net: bridge: add ...
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
  
  static ssize_t multicast_stats_enabled_show(struct device *d,
  					    struct device_attribute *attr,
  					    char *buf)
  {
  	struct net_bridge *br = to_bridge(d);
  
  	return sprintf(buf, "%u
  ", br->multicast_stats_enabled);
  }
  
  static int set_stats_enabled(struct net_bridge *br, unsigned long val)
  {
  	br->multicast_stats_enabled = !!val;
  	return 0;
  }
  
  static ssize_t multicast_stats_enabled_store(struct device *d,
  					     struct device_attribute *attr,
  					     const char *buf,
  					     size_t len)
  {
  	return store_bridge_parm(d, buf, len, set_stats_enabled);
  }
  static DEVICE_ATTR_RW(multicast_stats_enabled);
aa2ae3e71   Nikolay Aleksandrov   bridge: mcast: ad...
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
  
  #if IS_ENABLED(CONFIG_IPV6)
  static ssize_t multicast_mld_version_show(struct device *d,
  					  struct device_attribute *attr,
  					  char *buf)
  {
  	struct net_bridge *br = to_bridge(d);
  
  	return sprintf(buf, "%u
  ", br->multicast_mld_version);
  }
  
  static ssize_t multicast_mld_version_store(struct device *d,
  					   struct device_attribute *attr,
  					   const char *buf, size_t len)
  {
  	return store_bridge_parm(d, buf, len, br_multicast_set_mld_version);
  }
  static DEVICE_ATTR_RW(multicast_mld_version);
  #endif
0909e1175   Herbert Xu   bridge: Add multi...
674
  #endif
34666d467   Pablo Neira Ayuso   netfilter: bridge...
675
  #if IS_ENABLED(CONFIG_BRIDGE_NETFILTER)
fbf2671bb   sfeldma@cumulusnetworks.com   bridge: use DEVIC...
676
  static ssize_t nf_call_iptables_show(
4df53d8ba   Patrick McHardy   bridge: add per b...
677
678
679
680
681
682
683
684
685
686
687
688
  	struct device *d, struct device_attribute *attr, char *buf)
  {
  	struct net_bridge *br = to_bridge(d);
  	return sprintf(buf, "%u
  ", br->nf_call_iptables);
  }
  
  static int set_nf_call_iptables(struct net_bridge *br, unsigned long val)
  {
  	br->nf_call_iptables = val ? true : false;
  	return 0;
  }
fbf2671bb   sfeldma@cumulusnetworks.com   bridge: use DEVIC...
689
  static ssize_t nf_call_iptables_store(
4df53d8ba   Patrick McHardy   bridge: add per b...
690
691
692
693
694
  	struct device *d, struct device_attribute *attr, const char *buf,
  	size_t len)
  {
  	return store_bridge_parm(d, buf, len, set_nf_call_iptables);
  }
fbf2671bb   sfeldma@cumulusnetworks.com   bridge: use DEVIC...
695
  static DEVICE_ATTR_RW(nf_call_iptables);
4df53d8ba   Patrick McHardy   bridge: add per b...
696

fbf2671bb   sfeldma@cumulusnetworks.com   bridge: use DEVIC...
697
  static ssize_t nf_call_ip6tables_show(
4df53d8ba   Patrick McHardy   bridge: add per b...
698
699
700
701
702
703
704
705
706
707
708
709
  	struct device *d, struct device_attribute *attr, char *buf)
  {
  	struct net_bridge *br = to_bridge(d);
  	return sprintf(buf, "%u
  ", br->nf_call_ip6tables);
  }
  
  static int set_nf_call_ip6tables(struct net_bridge *br, unsigned long val)
  {
  	br->nf_call_ip6tables = val ? true : false;
  	return 0;
  }
fbf2671bb   sfeldma@cumulusnetworks.com   bridge: use DEVIC...
710
  static ssize_t nf_call_ip6tables_store(
4df53d8ba   Patrick McHardy   bridge: add per b...
711
712
713
714
715
  	struct device *d, struct device_attribute *attr, const char *buf,
  	size_t len)
  {
  	return store_bridge_parm(d, buf, len, set_nf_call_ip6tables);
  }
fbf2671bb   sfeldma@cumulusnetworks.com   bridge: use DEVIC...
716
  static DEVICE_ATTR_RW(nf_call_ip6tables);
4df53d8ba   Patrick McHardy   bridge: add per b...
717

fbf2671bb   sfeldma@cumulusnetworks.com   bridge: use DEVIC...
718
  static ssize_t nf_call_arptables_show(
4df53d8ba   Patrick McHardy   bridge: add per b...
719
720
721
722
723
724
725
726
727
728
729
730
  	struct device *d, struct device_attribute *attr, char *buf)
  {
  	struct net_bridge *br = to_bridge(d);
  	return sprintf(buf, "%u
  ", br->nf_call_arptables);
  }
  
  static int set_nf_call_arptables(struct net_bridge *br, unsigned long val)
  {
  	br->nf_call_arptables = val ? true : false;
  	return 0;
  }
fbf2671bb   sfeldma@cumulusnetworks.com   bridge: use DEVIC...
731
  static ssize_t nf_call_arptables_store(
4df53d8ba   Patrick McHardy   bridge: add per b...
732
733
734
735
736
  	struct device *d, struct device_attribute *attr, const char *buf,
  	size_t len)
  {
  	return store_bridge_parm(d, buf, len, set_nf_call_arptables);
  }
fbf2671bb   sfeldma@cumulusnetworks.com   bridge: use DEVIC...
737
  static DEVICE_ATTR_RW(nf_call_arptables);
4df53d8ba   Patrick McHardy   bridge: add per b...
738
  #endif
243a2e63f   Vlad Yasevich   bridge: Add vlan ...
739
  #ifdef CONFIG_BRIDGE_VLAN_FILTERING
fbf2671bb   sfeldma@cumulusnetworks.com   bridge: use DEVIC...
740
  static ssize_t vlan_filtering_show(struct device *d,
243a2e63f   Vlad Yasevich   bridge: Add vlan ...
741
742
743
744
745
746
747
  				   struct device_attribute *attr,
  				   char *buf)
  {
  	struct net_bridge *br = to_bridge(d);
  	return sprintf(buf, "%d
  ", br->vlan_enabled);
  }
fbf2671bb   sfeldma@cumulusnetworks.com   bridge: use DEVIC...
748
  static ssize_t vlan_filtering_store(struct device *d,
243a2e63f   Vlad Yasevich   bridge: Add vlan ...
749
750
751
752
753
  				    struct device_attribute *attr,
  				    const char *buf, size_t len)
  {
  	return store_bridge_parm(d, buf, len, br_vlan_filter_toggle);
  }
fbf2671bb   sfeldma@cumulusnetworks.com   bridge: use DEVIC...
754
  static DEVICE_ATTR_RW(vlan_filtering);
204177f3f   Toshiaki Makita   bridge: Support 8...
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
  
  static ssize_t vlan_protocol_show(struct device *d,
  				  struct device_attribute *attr,
  				  char *buf)
  {
  	struct net_bridge *br = to_bridge(d);
  	return sprintf(buf, "%#06x
  ", ntohs(br->vlan_proto));
  }
  
  static ssize_t vlan_protocol_store(struct device *d,
  				   struct device_attribute *attr,
  				   const char *buf, size_t len)
  {
  	return store_bridge_parm(d, buf, len, br_vlan_set_proto);
  }
  static DEVICE_ATTR_RW(vlan_protocol);
96a20d9d7   Vlad Yasevich   bridge: Add a def...
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
  
  static ssize_t default_pvid_show(struct device *d,
  				 struct device_attribute *attr,
  				 char *buf)
  {
  	struct net_bridge *br = to_bridge(d);
  	return sprintf(buf, "%d
  ", br->default_pvid);
  }
  
  static ssize_t default_pvid_store(struct device *d,
  				  struct device_attribute *attr,
  				  const char *buf, size_t len)
  {
  	return store_bridge_parm(d, buf, len, br_vlan_set_default_pvid);
  }
  static DEVICE_ATTR_RW(default_pvid);
6dada9b10   Nikolay Aleksandrov   bridge: vlan: lea...
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
  
  static ssize_t vlan_stats_enabled_show(struct device *d,
  				       struct device_attribute *attr,
  				       char *buf)
  {
  	struct net_bridge *br = to_bridge(d);
  	return sprintf(buf, "%u
  ", br->vlan_stats_enabled);
  }
  
  static ssize_t vlan_stats_enabled_store(struct device *d,
  					struct device_attribute *attr,
  					const char *buf, size_t len)
  {
  	return store_bridge_parm(d, buf, len, br_vlan_set_stats);
  }
  static DEVICE_ATTR_RW(vlan_stats_enabled);
243a2e63f   Vlad Yasevich   bridge: Add vlan ...
806
  #endif
0909e1175   Herbert Xu   bridge: Add multi...
807

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
808
  static struct attribute *bridge_attrs[] = {
43cb76d91   Greg Kroah-Hartman   Network: convert ...
809
810
811
812
813
  	&dev_attr_forward_delay.attr,
  	&dev_attr_hello_time.attr,
  	&dev_attr_max_age.attr,
  	&dev_attr_ageing_time.attr,
  	&dev_attr_stp_state.attr,
515853cce   stephen hemminger   bridge: allow for...
814
  	&dev_attr_group_fwd_mask.attr,
43cb76d91   Greg Kroah-Hartman   Network: convert ...
815
816
817
818
819
820
821
822
823
824
825
826
  	&dev_attr_priority.attr,
  	&dev_attr_bridge_id.attr,
  	&dev_attr_root_id.attr,
  	&dev_attr_root_path_cost.attr,
  	&dev_attr_root_port.attr,
  	&dev_attr_topology_change.attr,
  	&dev_attr_topology_change_detected.attr,
  	&dev_attr_hello_timer.attr,
  	&dev_attr_tcn_timer.attr,
  	&dev_attr_topology_change_timer.attr,
  	&dev_attr_gc_timer.attr,
  	&dev_attr_group_addr.attr,
9cf637473   Stephen Hemminger   bridge: add sysfs...
827
  	&dev_attr_flush.attr,
0909e1175   Herbert Xu   bridge: Add multi...
828
829
  #ifdef CONFIG_BRIDGE_IGMP_SNOOPING
  	&dev_attr_multicast_router.attr,
561f1103a   Herbert Xu   bridge: Add multi...
830
  	&dev_attr_multicast_snooping.attr,
c5c232605   Herbert Xu   bridge: Add multi...
831
  	&dev_attr_multicast_querier.attr,
1c8ad5bfa   Cong Wang   bridge: use the b...
832
  	&dev_attr_multicast_query_use_ifaddr.attr,
b195167fc   Herbert Xu   bridge: Add hash ...
833
834
  	&dev_attr_hash_elasticity.attr,
  	&dev_attr_hash_max.attr,
d902eee43   Herbert Xu   bridge: Add multi...
835
836
837
838
839
840
841
842
  	&dev_attr_multicast_last_member_count.attr,
  	&dev_attr_multicast_startup_query_count.attr,
  	&dev_attr_multicast_last_member_interval.attr,
  	&dev_attr_multicast_membership_interval.attr,
  	&dev_attr_multicast_querier_interval.attr,
  	&dev_attr_multicast_query_interval.attr,
  	&dev_attr_multicast_query_response_interval.attr,
  	&dev_attr_multicast_startup_query_interval.attr,
1080ab95e   Nikolay Aleksandrov   net: bridge: add ...
843
  	&dev_attr_multicast_stats_enabled.attr,
5e9235853   Nikolay Aleksandrov   bridge: mcast: ad...
844
  	&dev_attr_multicast_igmp_version.attr,
aa2ae3e71   Nikolay Aleksandrov   bridge: mcast: ad...
845
846
847
  #if IS_ENABLED(CONFIG_IPV6)
  	&dev_attr_multicast_mld_version.attr,
  #endif
0909e1175   Herbert Xu   bridge: Add multi...
848
  #endif
34666d467   Pablo Neira Ayuso   netfilter: bridge...
849
  #if IS_ENABLED(CONFIG_BRIDGE_NETFILTER)
4df53d8ba   Patrick McHardy   bridge: add per b...
850
851
852
853
  	&dev_attr_nf_call_iptables.attr,
  	&dev_attr_nf_call_ip6tables.attr,
  	&dev_attr_nf_call_arptables.attr,
  #endif
243a2e63f   Vlad Yasevich   bridge: Add vlan ...
854
855
  #ifdef CONFIG_BRIDGE_VLAN_FILTERING
  	&dev_attr_vlan_filtering.attr,
204177f3f   Toshiaki Makita   bridge: Support 8...
856
  	&dev_attr_vlan_protocol.attr,
96a20d9d7   Vlad Yasevich   bridge: Add a def...
857
  	&dev_attr_default_pvid.attr,
6dada9b10   Nikolay Aleksandrov   bridge: vlan: lea...
858
  	&dev_attr_vlan_stats_enabled.attr,
243a2e63f   Vlad Yasevich   bridge: Add vlan ...
859
  #endif
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
860
861
  	NULL
  };
cddbb79f7   Arvind Yadav   net: bridge: cons...
862
  static const struct attribute_group bridge_group = {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
863
864
865
866
867
868
869
870
871
872
  	.name = SYSFS_BRIDGE_ATTR,
  	.attrs = bridge_attrs,
  };
  
  /*
   * Export the forwarding information table as a binary file
   * The records are struct __fdb_entry.
   *
   * Returns the number of bytes read.
   */
2c3c8bea6   Chris Wright   sysfs: add struct...
873
  static ssize_t brforward_read(struct file *filp, struct kobject *kobj,
91a690295   Zhang Rui   sysfs: add parame...
874
875
  			      struct bin_attribute *bin_attr,
  			      char *buf, loff_t off, size_t count)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
876
  {
aeb7ed14f   Geliang Tang   bridge: use kobj_...
877
  	struct device *dev = kobj_to_dev(kobj);
43cb76d91   Greg Kroah-Hartman   Network: convert ...
878
  	struct net_bridge *br = to_bridge(dev);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
879
880
881
882
883
  	int n;
  
  	/* must read whole records */
  	if (off % sizeof(struct __fdb_entry) != 0)
  		return -EINVAL;
9d6f229fc   YOSHIFUJI Hideaki   [NET] BRIDGE: Fix...
884
  	n =  br_fdb_fillbuf(br, buf,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
885
886
887
888
889
  			    count / sizeof(struct __fdb_entry),
  			    off / sizeof(struct __fdb_entry));
  
  	if (n > 0)
  		n *= sizeof(struct __fdb_entry);
9d6f229fc   YOSHIFUJI Hideaki   [NET] BRIDGE: Fix...
890

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
891
892
893
894
895
  	return n;
  }
  
  static struct bin_attribute bridge_forward = {
  	.attr = { .name = SYSFS_BRIDGE_FDB,
7b595756e   Tejun Heo   sysfs: kill unnec...
896
  		  .mode = S_IRUGO, },
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
  	.read = brforward_read,
  };
  
  /*
   * Add entries in sysfs onto the existing network class device
   * for the bridge.
   *   Adds a attribute group "bridge" containing tuning parameters.
   *   Binary attribute containing the forward table
   *   Sub directory to hold links to interfaces.
   *
   * Note: the ifobj exists only to be a subdirectory
   *   to hold links.  The ifobj exists in same data structure
   *   as it's parent the bridge so reference counting works.
   */
  int br_sysfs_addbr(struct net_device *dev)
  {
43cb76d91   Greg Kroah-Hartman   Network: convert ...
913
  	struct kobject *brobj = &dev->dev.kobj;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
914
915
916
917
918
919
920
  	struct net_bridge *br = netdev_priv(dev);
  	int err;
  
  	err = sysfs_create_group(brobj, &bridge_group);
  	if (err) {
  		pr_info("%s: can't create group %s/%s
  ",
0dc47877a   Harvey Harrison   net: replace rema...
921
  			__func__, dev->name, bridge_group.name);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
922
923
924
925
926
  		goto out1;
  	}
  
  	err = sysfs_create_bin_file(brobj, &bridge_forward);
  	if (err) {
1842c4bef   Randy Dunlap   [BRIDGE]: correct...
927
928
  		pr_info("%s: can't create attribute file %s/%s
  ",
0dc47877a   Harvey Harrison   net: replace rema...
929
  			__func__, dev->name, bridge_forward.attr.name);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
930
931
  		goto out2;
  	}
43b98c4a6   Greg Kroah-Hartman   Kobject: change n...
932
933
  	br->ifobj = kobject_create_and_add(SYSFS_BRIDGE_PORT_SUBDIR, brobj);
  	if (!br->ifobj) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
934
935
  		pr_info("%s: can't add kobject (directory) %s/%s
  ",
0dc47877a   Harvey Harrison   net: replace rema...
936
  			__func__, dev->name, SYSFS_BRIDGE_PORT_SUBDIR);
b59589635   Pan Bian   net: bridge: set ...
937
  		err = -ENOMEM;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
938
939
940
941
  		goto out3;
  	}
  	return 0;
   out3:
43cb76d91   Greg Kroah-Hartman   Network: convert ...
942
  	sysfs_remove_bin_file(&dev->dev.kobj, &bridge_forward);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
943
   out2:
43cb76d91   Greg Kroah-Hartman   Network: convert ...
944
  	sysfs_remove_group(&dev->dev.kobj, &bridge_group);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
945
946
947
948
949
950
951
   out1:
  	return err;
  
  }
  
  void br_sysfs_delbr(struct net_device *dev)
  {
43cb76d91   Greg Kroah-Hartman   Network: convert ...
952
  	struct kobject *kobj = &dev->dev.kobj;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
953
  	struct net_bridge *br = netdev_priv(dev);
78a2d906b   Greg Kroah-Hartman   Kobject: convert ...
954
  	kobject_put(br->ifobj);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
955
956
957
  	sysfs_remove_bin_file(kobj, &bridge_forward);
  	sysfs_remove_group(kobj, &bridge_group);
  }