Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/net/bridge/br_sysfs_br.c
15109 views
1
/*
2
* Sysfs attributes of bridge ports
3
* Linux ethernet bridge
4
*
5
* Authors:
6
* Stephen Hemminger <[email protected]>
7
*
8
* This program is free software; you can redistribute it and/or
9
* modify it under the terms of the GNU General Public License
10
* as published by the Free Software Foundation; either version
11
* 2 of the License, or (at your option) any later version.
12
*/
13
14
#include <linux/capability.h>
15
#include <linux/kernel.h>
16
#include <linux/netdevice.h>
17
#include <linux/if_bridge.h>
18
#include <linux/rtnetlink.h>
19
#include <linux/spinlock.h>
20
#include <linux/times.h>
21
22
#include "br_private.h"
23
24
#define to_dev(obj) container_of(obj, struct device, kobj)
25
#define to_bridge(cd) ((struct net_bridge *)netdev_priv(to_net_dev(cd)))
26
27
/*
28
* Common code for storing bridge parameters.
29
*/
30
static ssize_t store_bridge_parm(struct device *d,
31
const char *buf, size_t len,
32
int (*set)(struct net_bridge *, unsigned long))
33
{
34
struct net_bridge *br = to_bridge(d);
35
char *endp;
36
unsigned long val;
37
int err;
38
39
if (!capable(CAP_NET_ADMIN))
40
return -EPERM;
41
42
val = simple_strtoul(buf, &endp, 0);
43
if (endp == buf)
44
return -EINVAL;
45
46
err = (*set)(br, val);
47
return err ? err : len;
48
}
49
50
51
static ssize_t show_forward_delay(struct device *d,
52
struct device_attribute *attr, char *buf)
53
{
54
struct net_bridge *br = to_bridge(d);
55
return sprintf(buf, "%lu\n", jiffies_to_clock_t(br->forward_delay));
56
}
57
58
static ssize_t store_forward_delay(struct device *d,
59
struct device_attribute *attr,
60
const char *buf, size_t len)
61
{
62
return store_bridge_parm(d, buf, len, br_set_forward_delay);
63
}
64
static DEVICE_ATTR(forward_delay, S_IRUGO | S_IWUSR,
65
show_forward_delay, store_forward_delay);
66
67
static ssize_t show_hello_time(struct device *d, struct device_attribute *attr,
68
char *buf)
69
{
70
return sprintf(buf, "%lu\n",
71
jiffies_to_clock_t(to_bridge(d)->hello_time));
72
}
73
74
static ssize_t store_hello_time(struct device *d,
75
struct device_attribute *attr, const char *buf,
76
size_t len)
77
{
78
return store_bridge_parm(d, buf, len, br_set_hello_time);
79
}
80
static DEVICE_ATTR(hello_time, S_IRUGO | S_IWUSR, show_hello_time,
81
store_hello_time);
82
83
static ssize_t show_max_age(struct device *d, struct device_attribute *attr,
84
char *buf)
85
{
86
return sprintf(buf, "%lu\n",
87
jiffies_to_clock_t(to_bridge(d)->max_age));
88
}
89
90
static ssize_t store_max_age(struct device *d, struct device_attribute *attr,
91
const char *buf, size_t len)
92
{
93
return store_bridge_parm(d, buf, len, br_set_max_age);
94
}
95
static DEVICE_ATTR(max_age, S_IRUGO | S_IWUSR, show_max_age, store_max_age);
96
97
static ssize_t show_ageing_time(struct device *d,
98
struct device_attribute *attr, char *buf)
99
{
100
struct net_bridge *br = to_bridge(d);
101
return sprintf(buf, "%lu\n", jiffies_to_clock_t(br->ageing_time));
102
}
103
104
static int set_ageing_time(struct net_bridge *br, unsigned long val)
105
{
106
br->ageing_time = clock_t_to_jiffies(val);
107
return 0;
108
}
109
110
static ssize_t store_ageing_time(struct device *d,
111
struct device_attribute *attr,
112
const char *buf, size_t len)
113
{
114
return store_bridge_parm(d, buf, len, set_ageing_time);
115
}
116
static DEVICE_ATTR(ageing_time, S_IRUGO | S_IWUSR, show_ageing_time,
117
store_ageing_time);
118
119
static ssize_t show_stp_state(struct device *d,
120
struct device_attribute *attr, char *buf)
121
{
122
struct net_bridge *br = to_bridge(d);
123
return sprintf(buf, "%d\n", br->stp_enabled);
124
}
125
126
127
static ssize_t store_stp_state(struct device *d,
128
struct device_attribute *attr, const char *buf,
129
size_t len)
130
{
131
struct net_bridge *br = to_bridge(d);
132
char *endp;
133
unsigned long val;
134
135
if (!capable(CAP_NET_ADMIN))
136
return -EPERM;
137
138
val = simple_strtoul(buf, &endp, 0);
139
if (endp == buf)
140
return -EINVAL;
141
142
if (!rtnl_trylock())
143
return restart_syscall();
144
br_stp_set_enabled(br, val);
145
rtnl_unlock();
146
147
return len;
148
}
149
static DEVICE_ATTR(stp_state, S_IRUGO | S_IWUSR, show_stp_state,
150
store_stp_state);
151
152
static ssize_t show_priority(struct device *d, struct device_attribute *attr,
153
char *buf)
154
{
155
struct net_bridge *br = to_bridge(d);
156
return sprintf(buf, "%d\n",
157
(br->bridge_id.prio[0] << 8) | br->bridge_id.prio[1]);
158
}
159
160
static int set_priority(struct net_bridge *br, unsigned long val)
161
{
162
br_stp_set_bridge_priority(br, (u16) val);
163
return 0;
164
}
165
166
static ssize_t store_priority(struct device *d, struct device_attribute *attr,
167
const char *buf, size_t len)
168
{
169
return store_bridge_parm(d, buf, len, set_priority);
170
}
171
static DEVICE_ATTR(priority, S_IRUGO | S_IWUSR, show_priority, store_priority);
172
173
static ssize_t show_root_id(struct device *d, struct device_attribute *attr,
174
char *buf)
175
{
176
return br_show_bridge_id(buf, &to_bridge(d)->designated_root);
177
}
178
static DEVICE_ATTR(root_id, S_IRUGO, show_root_id, NULL);
179
180
static ssize_t show_bridge_id(struct device *d, struct device_attribute *attr,
181
char *buf)
182
{
183
return br_show_bridge_id(buf, &to_bridge(d)->bridge_id);
184
}
185
static DEVICE_ATTR(bridge_id, S_IRUGO, show_bridge_id, NULL);
186
187
static ssize_t show_root_port(struct device *d, struct device_attribute *attr,
188
char *buf)
189
{
190
return sprintf(buf, "%d\n", to_bridge(d)->root_port);
191
}
192
static DEVICE_ATTR(root_port, S_IRUGO, show_root_port, NULL);
193
194
static ssize_t show_root_path_cost(struct device *d,
195
struct device_attribute *attr, char *buf)
196
{
197
return sprintf(buf, "%d\n", to_bridge(d)->root_path_cost);
198
}
199
static DEVICE_ATTR(root_path_cost, S_IRUGO, show_root_path_cost, NULL);
200
201
static ssize_t show_topology_change(struct device *d,
202
struct device_attribute *attr, char *buf)
203
{
204
return sprintf(buf, "%d\n", to_bridge(d)->topology_change);
205
}
206
static DEVICE_ATTR(topology_change, S_IRUGO, show_topology_change, NULL);
207
208
static ssize_t show_topology_change_detected(struct device *d,
209
struct device_attribute *attr,
210
char *buf)
211
{
212
struct net_bridge *br = to_bridge(d);
213
return sprintf(buf, "%d\n", br->topology_change_detected);
214
}
215
static DEVICE_ATTR(topology_change_detected, S_IRUGO,
216
show_topology_change_detected, NULL);
217
218
static ssize_t show_hello_timer(struct device *d,
219
struct device_attribute *attr, char *buf)
220
{
221
struct net_bridge *br = to_bridge(d);
222
return sprintf(buf, "%ld\n", br_timer_value(&br->hello_timer));
223
}
224
static DEVICE_ATTR(hello_timer, S_IRUGO, show_hello_timer, NULL);
225
226
static ssize_t show_tcn_timer(struct device *d, struct device_attribute *attr,
227
char *buf)
228
{
229
struct net_bridge *br = to_bridge(d);
230
return sprintf(buf, "%ld\n", br_timer_value(&br->tcn_timer));
231
}
232
static DEVICE_ATTR(tcn_timer, S_IRUGO, show_tcn_timer, NULL);
233
234
static ssize_t show_topology_change_timer(struct device *d,
235
struct device_attribute *attr,
236
char *buf)
237
{
238
struct net_bridge *br = to_bridge(d);
239
return sprintf(buf, "%ld\n", br_timer_value(&br->topology_change_timer));
240
}
241
static DEVICE_ATTR(topology_change_timer, S_IRUGO, show_topology_change_timer,
242
NULL);
243
244
static ssize_t show_gc_timer(struct device *d, struct device_attribute *attr,
245
char *buf)
246
{
247
struct net_bridge *br = to_bridge(d);
248
return sprintf(buf, "%ld\n", br_timer_value(&br->gc_timer));
249
}
250
static DEVICE_ATTR(gc_timer, S_IRUGO, show_gc_timer, NULL);
251
252
static ssize_t show_group_addr(struct device *d,
253
struct device_attribute *attr, char *buf)
254
{
255
struct net_bridge *br = to_bridge(d);
256
return sprintf(buf, "%x:%x:%x:%x:%x:%x\n",
257
br->group_addr[0], br->group_addr[1],
258
br->group_addr[2], br->group_addr[3],
259
br->group_addr[4], br->group_addr[5]);
260
}
261
262
static ssize_t store_group_addr(struct device *d,
263
struct device_attribute *attr,
264
const char *buf, size_t len)
265
{
266
struct net_bridge *br = to_bridge(d);
267
unsigned new_addr[6];
268
int i;
269
270
if (!capable(CAP_NET_ADMIN))
271
return -EPERM;
272
273
if (sscanf(buf, "%x:%x:%x:%x:%x:%x",
274
&new_addr[0], &new_addr[1], &new_addr[2],
275
&new_addr[3], &new_addr[4], &new_addr[5]) != 6)
276
return -EINVAL;
277
278
/* Must be 01:80:c2:00:00:0X */
279
for (i = 0; i < 5; i++)
280
if (new_addr[i] != br_group_address[i])
281
return -EINVAL;
282
283
if (new_addr[5] & ~0xf)
284
return -EINVAL;
285
286
if (new_addr[5] == 1 || /* 802.3x Pause address */
287
new_addr[5] == 2 || /* 802.3ad Slow protocols */
288
new_addr[5] == 3) /* 802.1X PAE address */
289
return -EINVAL;
290
291
spin_lock_bh(&br->lock);
292
for (i = 0; i < 6; i++)
293
br->group_addr[i] = new_addr[i];
294
spin_unlock_bh(&br->lock);
295
return len;
296
}
297
298
static DEVICE_ATTR(group_addr, S_IRUGO | S_IWUSR,
299
show_group_addr, store_group_addr);
300
301
static ssize_t store_flush(struct device *d,
302
struct device_attribute *attr,
303
const char *buf, size_t len)
304
{
305
struct net_bridge *br = to_bridge(d);
306
307
if (!capable(CAP_NET_ADMIN))
308
return -EPERM;
309
310
br_fdb_flush(br);
311
return len;
312
}
313
static DEVICE_ATTR(flush, S_IWUSR, NULL, store_flush);
314
315
#ifdef CONFIG_BRIDGE_IGMP_SNOOPING
316
static ssize_t show_multicast_router(struct device *d,
317
struct device_attribute *attr, char *buf)
318
{
319
struct net_bridge *br = to_bridge(d);
320
return sprintf(buf, "%d\n", br->multicast_router);
321
}
322
323
static ssize_t store_multicast_router(struct device *d,
324
struct device_attribute *attr,
325
const char *buf, size_t len)
326
{
327
return store_bridge_parm(d, buf, len, br_multicast_set_router);
328
}
329
static DEVICE_ATTR(multicast_router, S_IRUGO | S_IWUSR, show_multicast_router,
330
store_multicast_router);
331
332
static ssize_t show_multicast_snooping(struct device *d,
333
struct device_attribute *attr,
334
char *buf)
335
{
336
struct net_bridge *br = to_bridge(d);
337
return sprintf(buf, "%d\n", !br->multicast_disabled);
338
}
339
340
static ssize_t store_multicast_snooping(struct device *d,
341
struct device_attribute *attr,
342
const char *buf, size_t len)
343
{
344
return store_bridge_parm(d, buf, len, br_multicast_toggle);
345
}
346
static DEVICE_ATTR(multicast_snooping, S_IRUGO | S_IWUSR,
347
show_multicast_snooping, store_multicast_snooping);
348
349
static ssize_t show_hash_elasticity(struct device *d,
350
struct device_attribute *attr, char *buf)
351
{
352
struct net_bridge *br = to_bridge(d);
353
return sprintf(buf, "%u\n", br->hash_elasticity);
354
}
355
356
static int set_elasticity(struct net_bridge *br, unsigned long val)
357
{
358
br->hash_elasticity = val;
359
return 0;
360
}
361
362
static ssize_t store_hash_elasticity(struct device *d,
363
struct device_attribute *attr,
364
const char *buf, size_t len)
365
{
366
return store_bridge_parm(d, buf, len, set_elasticity);
367
}
368
static DEVICE_ATTR(hash_elasticity, S_IRUGO | S_IWUSR, show_hash_elasticity,
369
store_hash_elasticity);
370
371
static ssize_t show_hash_max(struct device *d, struct device_attribute *attr,
372
char *buf)
373
{
374
struct net_bridge *br = to_bridge(d);
375
return sprintf(buf, "%u\n", br->hash_max);
376
}
377
378
static ssize_t store_hash_max(struct device *d, struct device_attribute *attr,
379
const char *buf, size_t len)
380
{
381
return store_bridge_parm(d, buf, len, br_multicast_set_hash_max);
382
}
383
static DEVICE_ATTR(hash_max, S_IRUGO | S_IWUSR, show_hash_max,
384
store_hash_max);
385
386
static ssize_t show_multicast_last_member_count(struct device *d,
387
struct device_attribute *attr,
388
char *buf)
389
{
390
struct net_bridge *br = to_bridge(d);
391
return sprintf(buf, "%u\n", br->multicast_last_member_count);
392
}
393
394
static int set_last_member_count(struct net_bridge *br, unsigned long val)
395
{
396
br->multicast_last_member_count = val;
397
return 0;
398
}
399
400
static ssize_t store_multicast_last_member_count(struct device *d,
401
struct device_attribute *attr,
402
const char *buf, size_t len)
403
{
404
return store_bridge_parm(d, buf, len, set_last_member_count);
405
}
406
static DEVICE_ATTR(multicast_last_member_count, S_IRUGO | S_IWUSR,
407
show_multicast_last_member_count,
408
store_multicast_last_member_count);
409
410
static ssize_t show_multicast_startup_query_count(
411
struct device *d, struct device_attribute *attr, char *buf)
412
{
413
struct net_bridge *br = to_bridge(d);
414
return sprintf(buf, "%u\n", br->multicast_startup_query_count);
415
}
416
417
static int set_startup_query_count(struct net_bridge *br, unsigned long val)
418
{
419
br->multicast_startup_query_count = val;
420
return 0;
421
}
422
423
static ssize_t store_multicast_startup_query_count(
424
struct device *d, struct device_attribute *attr, const char *buf,
425
size_t len)
426
{
427
return store_bridge_parm(d, buf, len, set_startup_query_count);
428
}
429
static DEVICE_ATTR(multicast_startup_query_count, S_IRUGO | S_IWUSR,
430
show_multicast_startup_query_count,
431
store_multicast_startup_query_count);
432
433
static ssize_t show_multicast_last_member_interval(
434
struct device *d, struct device_attribute *attr, char *buf)
435
{
436
struct net_bridge *br = to_bridge(d);
437
return sprintf(buf, "%lu\n",
438
jiffies_to_clock_t(br->multicast_last_member_interval));
439
}
440
441
static int set_last_member_interval(struct net_bridge *br, unsigned long val)
442
{
443
br->multicast_last_member_interval = clock_t_to_jiffies(val);
444
return 0;
445
}
446
447
static ssize_t store_multicast_last_member_interval(
448
struct device *d, struct device_attribute *attr, const char *buf,
449
size_t len)
450
{
451
return store_bridge_parm(d, buf, len, set_last_member_interval);
452
}
453
static DEVICE_ATTR(multicast_last_member_interval, S_IRUGO | S_IWUSR,
454
show_multicast_last_member_interval,
455
store_multicast_last_member_interval);
456
457
static ssize_t show_multicast_membership_interval(
458
struct device *d, struct device_attribute *attr, char *buf)
459
{
460
struct net_bridge *br = to_bridge(d);
461
return sprintf(buf, "%lu\n",
462
jiffies_to_clock_t(br->multicast_membership_interval));
463
}
464
465
static int set_membership_interval(struct net_bridge *br, unsigned long val)
466
{
467
br->multicast_membership_interval = clock_t_to_jiffies(val);
468
return 0;
469
}
470
471
static ssize_t store_multicast_membership_interval(
472
struct device *d, struct device_attribute *attr, const char *buf,
473
size_t len)
474
{
475
return store_bridge_parm(d, buf, len, set_membership_interval);
476
}
477
static DEVICE_ATTR(multicast_membership_interval, S_IRUGO | S_IWUSR,
478
show_multicast_membership_interval,
479
store_multicast_membership_interval);
480
481
static ssize_t show_multicast_querier_interval(struct device *d,
482
struct device_attribute *attr,
483
char *buf)
484
{
485
struct net_bridge *br = to_bridge(d);
486
return sprintf(buf, "%lu\n",
487
jiffies_to_clock_t(br->multicast_querier_interval));
488
}
489
490
static int set_querier_interval(struct net_bridge *br, unsigned long val)
491
{
492
br->multicast_querier_interval = clock_t_to_jiffies(val);
493
return 0;
494
}
495
496
static ssize_t store_multicast_querier_interval(struct device *d,
497
struct device_attribute *attr,
498
const char *buf, size_t len)
499
{
500
return store_bridge_parm(d, buf, len, set_querier_interval);
501
}
502
static DEVICE_ATTR(multicast_querier_interval, S_IRUGO | S_IWUSR,
503
show_multicast_querier_interval,
504
store_multicast_querier_interval);
505
506
static ssize_t show_multicast_query_interval(struct device *d,
507
struct device_attribute *attr,
508
char *buf)
509
{
510
struct net_bridge *br = to_bridge(d);
511
return sprintf(buf, "%lu\n",
512
jiffies_to_clock_t(br->multicast_query_interval));
513
}
514
515
static int set_query_interval(struct net_bridge *br, unsigned long val)
516
{
517
br->multicast_query_interval = clock_t_to_jiffies(val);
518
return 0;
519
}
520
521
static ssize_t store_multicast_query_interval(struct device *d,
522
struct device_attribute *attr,
523
const char *buf, size_t len)
524
{
525
return store_bridge_parm(d, buf, len, set_query_interval);
526
}
527
static DEVICE_ATTR(multicast_query_interval, S_IRUGO | S_IWUSR,
528
show_multicast_query_interval,
529
store_multicast_query_interval);
530
531
static ssize_t show_multicast_query_response_interval(
532
struct device *d, struct device_attribute *attr, char *buf)
533
{
534
struct net_bridge *br = to_bridge(d);
535
return sprintf(
536
buf, "%lu\n",
537
jiffies_to_clock_t(br->multicast_query_response_interval));
538
}
539
540
static int set_query_response_interval(struct net_bridge *br, unsigned long val)
541
{
542
br->multicast_query_response_interval = clock_t_to_jiffies(val);
543
return 0;
544
}
545
546
static ssize_t store_multicast_query_response_interval(
547
struct device *d, struct device_attribute *attr, const char *buf,
548
size_t len)
549
{
550
return store_bridge_parm(d, buf, len, set_query_response_interval);
551
}
552
static DEVICE_ATTR(multicast_query_response_interval, S_IRUGO | S_IWUSR,
553
show_multicast_query_response_interval,
554
store_multicast_query_response_interval);
555
556
static ssize_t show_multicast_startup_query_interval(
557
struct device *d, struct device_attribute *attr, char *buf)
558
{
559
struct net_bridge *br = to_bridge(d);
560
return sprintf(
561
buf, "%lu\n",
562
jiffies_to_clock_t(br->multicast_startup_query_interval));
563
}
564
565
static int set_startup_query_interval(struct net_bridge *br, unsigned long val)
566
{
567
br->multicast_startup_query_interval = clock_t_to_jiffies(val);
568
return 0;
569
}
570
571
static ssize_t store_multicast_startup_query_interval(
572
struct device *d, struct device_attribute *attr, const char *buf,
573
size_t len)
574
{
575
return store_bridge_parm(d, buf, len, set_startup_query_interval);
576
}
577
static DEVICE_ATTR(multicast_startup_query_interval, S_IRUGO | S_IWUSR,
578
show_multicast_startup_query_interval,
579
store_multicast_startup_query_interval);
580
#endif
581
#ifdef CONFIG_BRIDGE_NETFILTER
582
static ssize_t show_nf_call_iptables(
583
struct device *d, struct device_attribute *attr, char *buf)
584
{
585
struct net_bridge *br = to_bridge(d);
586
return sprintf(buf, "%u\n", br->nf_call_iptables);
587
}
588
589
static int set_nf_call_iptables(struct net_bridge *br, unsigned long val)
590
{
591
br->nf_call_iptables = val ? true : false;
592
return 0;
593
}
594
595
static ssize_t store_nf_call_iptables(
596
struct device *d, struct device_attribute *attr, const char *buf,
597
size_t len)
598
{
599
return store_bridge_parm(d, buf, len, set_nf_call_iptables);
600
}
601
static DEVICE_ATTR(nf_call_iptables, S_IRUGO | S_IWUSR,
602
show_nf_call_iptables, store_nf_call_iptables);
603
604
static ssize_t show_nf_call_ip6tables(
605
struct device *d, struct device_attribute *attr, char *buf)
606
{
607
struct net_bridge *br = to_bridge(d);
608
return sprintf(buf, "%u\n", br->nf_call_ip6tables);
609
}
610
611
static int set_nf_call_ip6tables(struct net_bridge *br, unsigned long val)
612
{
613
br->nf_call_ip6tables = val ? true : false;
614
return 0;
615
}
616
617
static ssize_t store_nf_call_ip6tables(
618
struct device *d, struct device_attribute *attr, const char *buf,
619
size_t len)
620
{
621
return store_bridge_parm(d, buf, len, set_nf_call_ip6tables);
622
}
623
static DEVICE_ATTR(nf_call_ip6tables, S_IRUGO | S_IWUSR,
624
show_nf_call_ip6tables, store_nf_call_ip6tables);
625
626
static ssize_t show_nf_call_arptables(
627
struct device *d, struct device_attribute *attr, char *buf)
628
{
629
struct net_bridge *br = to_bridge(d);
630
return sprintf(buf, "%u\n", br->nf_call_arptables);
631
}
632
633
static int set_nf_call_arptables(struct net_bridge *br, unsigned long val)
634
{
635
br->nf_call_arptables = val ? true : false;
636
return 0;
637
}
638
639
static ssize_t store_nf_call_arptables(
640
struct device *d, struct device_attribute *attr, const char *buf,
641
size_t len)
642
{
643
return store_bridge_parm(d, buf, len, set_nf_call_arptables);
644
}
645
static DEVICE_ATTR(nf_call_arptables, S_IRUGO | S_IWUSR,
646
show_nf_call_arptables, store_nf_call_arptables);
647
#endif
648
649
static struct attribute *bridge_attrs[] = {
650
&dev_attr_forward_delay.attr,
651
&dev_attr_hello_time.attr,
652
&dev_attr_max_age.attr,
653
&dev_attr_ageing_time.attr,
654
&dev_attr_stp_state.attr,
655
&dev_attr_priority.attr,
656
&dev_attr_bridge_id.attr,
657
&dev_attr_root_id.attr,
658
&dev_attr_root_path_cost.attr,
659
&dev_attr_root_port.attr,
660
&dev_attr_topology_change.attr,
661
&dev_attr_topology_change_detected.attr,
662
&dev_attr_hello_timer.attr,
663
&dev_attr_tcn_timer.attr,
664
&dev_attr_topology_change_timer.attr,
665
&dev_attr_gc_timer.attr,
666
&dev_attr_group_addr.attr,
667
&dev_attr_flush.attr,
668
#ifdef CONFIG_BRIDGE_IGMP_SNOOPING
669
&dev_attr_multicast_router.attr,
670
&dev_attr_multicast_snooping.attr,
671
&dev_attr_hash_elasticity.attr,
672
&dev_attr_hash_max.attr,
673
&dev_attr_multicast_last_member_count.attr,
674
&dev_attr_multicast_startup_query_count.attr,
675
&dev_attr_multicast_last_member_interval.attr,
676
&dev_attr_multicast_membership_interval.attr,
677
&dev_attr_multicast_querier_interval.attr,
678
&dev_attr_multicast_query_interval.attr,
679
&dev_attr_multicast_query_response_interval.attr,
680
&dev_attr_multicast_startup_query_interval.attr,
681
#endif
682
#ifdef CONFIG_BRIDGE_NETFILTER
683
&dev_attr_nf_call_iptables.attr,
684
&dev_attr_nf_call_ip6tables.attr,
685
&dev_attr_nf_call_arptables.attr,
686
#endif
687
NULL
688
};
689
690
static struct attribute_group bridge_group = {
691
.name = SYSFS_BRIDGE_ATTR,
692
.attrs = bridge_attrs,
693
};
694
695
/*
696
* Export the forwarding information table as a binary file
697
* The records are struct __fdb_entry.
698
*
699
* Returns the number of bytes read.
700
*/
701
static ssize_t brforward_read(struct file *filp, struct kobject *kobj,
702
struct bin_attribute *bin_attr,
703
char *buf, loff_t off, size_t count)
704
{
705
struct device *dev = to_dev(kobj);
706
struct net_bridge *br = to_bridge(dev);
707
int n;
708
709
/* must read whole records */
710
if (off % sizeof(struct __fdb_entry) != 0)
711
return -EINVAL;
712
713
n = br_fdb_fillbuf(br, buf,
714
count / sizeof(struct __fdb_entry),
715
off / sizeof(struct __fdb_entry));
716
717
if (n > 0)
718
n *= sizeof(struct __fdb_entry);
719
720
return n;
721
}
722
723
static struct bin_attribute bridge_forward = {
724
.attr = { .name = SYSFS_BRIDGE_FDB,
725
.mode = S_IRUGO, },
726
.read = brforward_read,
727
};
728
729
/*
730
* Add entries in sysfs onto the existing network class device
731
* for the bridge.
732
* Adds a attribute group "bridge" containing tuning parameters.
733
* Binary attribute containing the forward table
734
* Sub directory to hold links to interfaces.
735
*
736
* Note: the ifobj exists only to be a subdirectory
737
* to hold links. The ifobj exists in same data structure
738
* as it's parent the bridge so reference counting works.
739
*/
740
int br_sysfs_addbr(struct net_device *dev)
741
{
742
struct kobject *brobj = &dev->dev.kobj;
743
struct net_bridge *br = netdev_priv(dev);
744
int err;
745
746
err = sysfs_create_group(brobj, &bridge_group);
747
if (err) {
748
pr_info("%s: can't create group %s/%s\n",
749
__func__, dev->name, bridge_group.name);
750
goto out1;
751
}
752
753
err = sysfs_create_bin_file(brobj, &bridge_forward);
754
if (err) {
755
pr_info("%s: can't create attribute file %s/%s\n",
756
__func__, dev->name, bridge_forward.attr.name);
757
goto out2;
758
}
759
760
br->ifobj = kobject_create_and_add(SYSFS_BRIDGE_PORT_SUBDIR, brobj);
761
if (!br->ifobj) {
762
pr_info("%s: can't add kobject (directory) %s/%s\n",
763
__func__, dev->name, SYSFS_BRIDGE_PORT_SUBDIR);
764
goto out3;
765
}
766
return 0;
767
out3:
768
sysfs_remove_bin_file(&dev->dev.kobj, &bridge_forward);
769
out2:
770
sysfs_remove_group(&dev->dev.kobj, &bridge_group);
771
out1:
772
return err;
773
774
}
775
776
void br_sysfs_delbr(struct net_device *dev)
777
{
778
struct kobject *kobj = &dev->dev.kobj;
779
struct net_bridge *br = netdev_priv(dev);
780
781
kobject_put(br->ifobj);
782
sysfs_remove_bin_file(kobj, &bridge_forward);
783
sysfs_remove_group(kobj, &bridge_group);
784
}
785
786