]> git.proxmox.com Git - mirror_iproute2.git/blob - ip/iplink_bridge.c
iplink: bridge: add support for IFLA_BR_MCAST_STATS_ENABLED
[mirror_iproute2.git] / ip / iplink_bridge.c
1 /*
2 * iplink_bridge.c Bridge device support
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version
7 * 2 of the License, or (at your option) any later version.
8 *
9 * Authors: Jiri Pirko <jiri@resnulli.us>
10 */
11
12 #include <stdio.h>
13 #include <stdlib.h>
14 #include <string.h>
15 #include <linux/if_link.h>
16 #include <netinet/ether.h>
17
18 #include "rt_names.h"
19 #include "utils.h"
20 #include "ip_common.h"
21
22 static void print_explain(FILE *f)
23 {
24 fprintf(f,
25 "Usage: ... bridge [ fdb_flush ]\n"
26 " [ forward_delay FORWARD_DELAY ]\n"
27 " [ hello_time HELLO_TIME ]\n"
28 " [ max_age MAX_AGE ]\n"
29 " [ ageing_time AGEING_TIME ]\n"
30 " [ stp_state STP_STATE ]\n"
31 " [ priority PRIORITY ]\n"
32 " [ group_fwd_mask MASK ]\n"
33 " [ group_address ADDRESS ]\n"
34 " [ vlan_filtering VLAN_FILTERING ]\n"
35 " [ vlan_protocol VLAN_PROTOCOL ]\n"
36 " [ vlan_default_pvid VLAN_DEFAULT_PVID ]\n"
37 " [ vlan_stats_enabled VLAN_STATS_ENABLED ]\n"
38 " [ mcast_snooping MULTICAST_SNOOPING ]\n"
39 " [ mcast_router MULTICAST_ROUTER ]\n"
40 " [ mcast_query_use_ifaddr MCAST_QUERY_USE_IFADDR ]\n"
41 " [ mcast_querier MULTICAST_QUERIER ]\n"
42 " [ mcast_hash_elasticity HASH_ELASTICITY ]\n"
43 " [ mcast_hash_max HASH_MAX ]\n"
44 " [ mcast_last_member_count LAST_MEMBER_COUNT ]\n"
45 " [ mcast_startup_query_count STARTUP_QUERY_COUNT ]\n"
46 " [ mcast_last_member_interval LAST_MEMBER_INTERVAL ]\n"
47 " [ mcast_membership_interval MEMBERSHIP_INTERVAL ]\n"
48 " [ mcast_querier_interval QUERIER_INTERVAL ]\n"
49 " [ mcast_query_interval QUERY_INTERVAL ]\n"
50 " [ mcast_query_response_interval QUERY_RESPONSE_INTERVAL ]\n"
51 " [ mcast_startup_query_interval STARTUP_QUERY_INTERVAL ]\n"
52 " [ mcast_stats_enabled MCAST_STATS_ENABLED ]\n"
53 " [ nf_call_iptables NF_CALL_IPTABLES ]\n"
54 " [ nf_call_ip6tables NF_CALL_IP6TABLES ]\n"
55 " [ nf_call_arptables NF_CALL_ARPTABLES ]\n"
56 "\n"
57 "Where: VLAN_PROTOCOL := { 802.1Q | 802.1ad }\n"
58 );
59 }
60
61 static void explain(void)
62 {
63 print_explain(stderr);
64 }
65
66 void br_dump_bridge_id(const struct ifla_bridge_id *id, char *buf, size_t len)
67 {
68 char eaddr[32];
69
70 ether_ntoa_r((const struct ether_addr *)id->addr, eaddr);
71 snprintf(buf, len, "%.2x%.2x.%s", id->prio[0], id->prio[1], eaddr);
72 }
73
74 static int bridge_parse_opt(struct link_util *lu, int argc, char **argv,
75 struct nlmsghdr *n)
76 {
77 __u32 val;
78
79 while (argc > 0) {
80 if (matches(*argv, "forward_delay") == 0) {
81 NEXT_ARG();
82 if (get_u32(&val, *argv, 0))
83 invarg("invalid forward_delay", *argv);
84
85 addattr32(n, 1024, IFLA_BR_FORWARD_DELAY, val);
86 } else if (matches(*argv, "hello_time") == 0) {
87 NEXT_ARG();
88 if (get_u32(&val, *argv, 0))
89 invarg("invalid hello_time", *argv);
90
91 addattr32(n, 1024, IFLA_BR_HELLO_TIME, val);
92 } else if (matches(*argv, "max_age") == 0) {
93 NEXT_ARG();
94 if (get_u32(&val, *argv, 0))
95 invarg("invalid max_age", *argv);
96
97 addattr32(n, 1024, IFLA_BR_MAX_AGE, val);
98 } else if (matches(*argv, "ageing_time") == 0) {
99 NEXT_ARG();
100 if (get_u32(&val, *argv, 0))
101 invarg("invalid ageing_time", *argv);
102
103 addattr32(n, 1024, IFLA_BR_AGEING_TIME, val);
104 } else if (matches(*argv, "stp_state") == 0) {
105 NEXT_ARG();
106 if (get_u32(&val, *argv, 0))
107 invarg("invalid stp_state", *argv);
108
109 addattr32(n, 1024, IFLA_BR_STP_STATE, val);
110 } else if (matches(*argv, "priority") == 0) {
111 __u16 prio;
112
113 NEXT_ARG();
114 if (get_u16(&prio, *argv, 0))
115 invarg("invalid priority", *argv);
116
117 addattr16(n, 1024, IFLA_BR_PRIORITY, prio);
118 } else if (matches(*argv, "vlan_filtering") == 0) {
119 __u8 vlan_filter;
120
121 NEXT_ARG();
122 if (get_u8(&vlan_filter, *argv, 0))
123 invarg("invalid vlan_filtering", *argv);
124
125 addattr8(n, 1024, IFLA_BR_VLAN_FILTERING, vlan_filter);
126 } else if (matches(*argv, "vlan_protocol") == 0) {
127 __u16 vlan_proto;
128
129 NEXT_ARG();
130 if (ll_proto_a2n(&vlan_proto, *argv))
131 invarg("invalid vlan_protocol", *argv);
132
133 addattr16(n, 1024, IFLA_BR_VLAN_PROTOCOL, vlan_proto);
134 } else if (matches(*argv, "group_fwd_mask") == 0) {
135 __u16 fwd_mask;
136
137 NEXT_ARG();
138 if (get_u16(&fwd_mask, *argv, 0))
139 invarg("invalid group_fwd_mask", *argv);
140
141 addattr16(n, 1024, IFLA_BR_GROUP_FWD_MASK, fwd_mask);
142 } else if (matches(*argv, "group_address") == 0) {
143 char llabuf[32];
144 int len;
145
146 NEXT_ARG();
147 len = ll_addr_a2n(llabuf, sizeof(llabuf), *argv);
148 if (len < 0)
149 return -1;
150 addattr_l(n, 1024, IFLA_BR_GROUP_ADDR, llabuf, len);
151 } else if (matches(*argv, "fdb_flush") == 0) {
152 addattr(n, 1024, IFLA_BR_FDB_FLUSH);
153 } else if (matches(*argv, "vlan_default_pvid") == 0) {
154 __u16 default_pvid;
155
156 NEXT_ARG();
157 if (get_u16(&default_pvid, *argv, 0))
158 invarg("invalid vlan_default_pvid", *argv);
159
160 addattr16(n, 1024, IFLA_BR_VLAN_DEFAULT_PVID,
161 default_pvid);
162 } else if (matches(*argv, "vlan_stats_enabled") == 0) {
163 __u8 vlan_stats_enabled;
164
165 NEXT_ARG();
166 if (get_u8(&vlan_stats_enabled, *argv, 0))
167 invarg("invalid vlan_stats_enabled", *argv);
168 addattr8(n, 1024, IFLA_BR_VLAN_STATS_ENABLED,
169 vlan_stats_enabled);
170 } else if (matches(*argv, "mcast_router") == 0) {
171 __u8 mcast_router;
172
173 NEXT_ARG();
174 if (get_u8(&mcast_router, *argv, 0))
175 invarg("invalid mcast_router", *argv);
176
177 addattr8(n, 1024, IFLA_BR_MCAST_ROUTER, mcast_router);
178 } else if (matches(*argv, "mcast_snooping") == 0) {
179 __u8 mcast_snoop;
180
181 NEXT_ARG();
182 if (get_u8(&mcast_snoop, *argv, 0))
183 invarg("invalid mcast_snooping", *argv);
184
185 addattr8(n, 1024, IFLA_BR_MCAST_SNOOPING, mcast_snoop);
186 } else if (matches(*argv, "mcast_query_use_ifaddr") == 0) {
187 __u8 mcast_qui;
188
189 NEXT_ARG();
190 if (get_u8(&mcast_qui, *argv, 0))
191 invarg("invalid mcast_query_use_ifaddr",
192 *argv);
193
194 addattr8(n, 1024, IFLA_BR_MCAST_QUERY_USE_IFADDR,
195 mcast_qui);
196 } else if (matches(*argv, "mcast_querier") == 0) {
197 __u8 mcast_querier;
198
199 NEXT_ARG();
200 if (get_u8(&mcast_querier, *argv, 0))
201 invarg("invalid mcast_querier", *argv);
202
203 addattr8(n, 1024, IFLA_BR_MCAST_QUERIER, mcast_querier);
204 } else if (matches(*argv, "mcast_hash_elasticity") == 0) {
205 __u32 mcast_hash_el;
206
207 NEXT_ARG();
208 if (get_u32(&mcast_hash_el, *argv, 0))
209 invarg("invalid mcast_hash_elasticity",
210 *argv);
211
212 addattr32(n, 1024, IFLA_BR_MCAST_HASH_ELASTICITY,
213 mcast_hash_el);
214 } else if (matches(*argv, "mcast_hash_max") == 0) {
215 __u32 mcast_hash_max;
216
217 NEXT_ARG();
218 if (get_u32(&mcast_hash_max, *argv, 0))
219 invarg("invalid mcast_hash_max", *argv);
220
221 addattr32(n, 1024, IFLA_BR_MCAST_HASH_MAX,
222 mcast_hash_max);
223 } else if (matches(*argv, "mcast_last_member_count") == 0) {
224 __u32 mcast_lmc;
225
226 NEXT_ARG();
227 if (get_u32(&mcast_lmc, *argv, 0))
228 invarg("invalid mcast_last_member_count",
229 *argv);
230
231 addattr32(n, 1024, IFLA_BR_MCAST_LAST_MEMBER_CNT,
232 mcast_lmc);
233 } else if (matches(*argv, "mcast_startup_query_count") == 0) {
234 __u32 mcast_sqc;
235
236 NEXT_ARG();
237 if (get_u32(&mcast_sqc, *argv, 0))
238 invarg("invalid mcast_startup_query_count",
239 *argv);
240
241 addattr32(n, 1024, IFLA_BR_MCAST_STARTUP_QUERY_CNT,
242 mcast_sqc);
243 } else if (matches(*argv, "mcast_last_member_interval") == 0) {
244 __u64 mcast_last_member_intvl;
245
246 NEXT_ARG();
247 if (get_u64(&mcast_last_member_intvl, *argv, 0))
248 invarg("invalid mcast_last_member_interval",
249 *argv);
250
251 addattr64(n, 1024, IFLA_BR_MCAST_LAST_MEMBER_INTVL,
252 mcast_last_member_intvl);
253 } else if (matches(*argv, "mcast_membership_interval") == 0) {
254 __u64 mcast_membership_intvl;
255
256 NEXT_ARG();
257 if (get_u64(&mcast_membership_intvl, *argv, 0))
258 invarg("invalid mcast_membership_interval",
259 *argv);
260
261 addattr64(n, 1024, IFLA_BR_MCAST_MEMBERSHIP_INTVL,
262 mcast_membership_intvl);
263 } else if (matches(*argv, "mcast_querier_interval") == 0) {
264 __u64 mcast_querier_intvl;
265
266 NEXT_ARG();
267 if (get_u64(&mcast_querier_intvl, *argv, 0))
268 invarg("invalid mcast_querier_interval",
269 *argv);
270
271 addattr64(n, 1024, IFLA_BR_MCAST_QUERIER_INTVL,
272 mcast_querier_intvl);
273 } else if (matches(*argv, "mcast_query_interval") == 0) {
274 __u64 mcast_query_intvl;
275
276 NEXT_ARG();
277 if (get_u64(&mcast_query_intvl, *argv, 0))
278 invarg("invalid mcast_query_interval",
279 *argv);
280
281 addattr64(n, 1024, IFLA_BR_MCAST_QUERY_INTVL,
282 mcast_query_intvl);
283 } else if (!matches(*argv, "mcast_query_response_interval")) {
284 __u64 mcast_query_resp_intvl;
285
286 NEXT_ARG();
287 if (get_u64(&mcast_query_resp_intvl, *argv, 0))
288 invarg("invalid mcast_query_response_interval",
289 *argv);
290
291 addattr64(n, 1024, IFLA_BR_MCAST_QUERY_RESPONSE_INTVL,
292 mcast_query_resp_intvl);
293 } else if (!matches(*argv, "mcast_startup_query_interval")) {
294 __u64 mcast_startup_query_intvl;
295
296 NEXT_ARG();
297 if (get_u64(&mcast_startup_query_intvl, *argv, 0))
298 invarg("invalid mcast_startup_query_interval",
299 *argv);
300
301 addattr64(n, 1024, IFLA_BR_MCAST_STARTUP_QUERY_INTVL,
302 mcast_startup_query_intvl);
303 } else if (matches(*argv, "mcast_stats_enabled") == 0) {
304 __u8 mcast_stats_enabled;
305
306 NEXT_ARG();
307 if (get_u8(&mcast_stats_enabled, *argv, 0))
308 invarg("invalid mcast_stats_enabled", *argv);
309 addattr8(n, 1024, IFLA_BR_MCAST_STATS_ENABLED,
310 mcast_stats_enabled);
311 } else if (matches(*argv, "nf_call_iptables") == 0) {
312 __u8 nf_call_ipt;
313
314 NEXT_ARG();
315 if (get_u8(&nf_call_ipt, *argv, 0))
316 invarg("invalid nf_call_iptables", *argv);
317
318 addattr8(n, 1024, IFLA_BR_NF_CALL_IPTABLES,
319 nf_call_ipt);
320 } else if (matches(*argv, "nf_call_ip6tables") == 0) {
321 __u8 nf_call_ip6t;
322
323 NEXT_ARG();
324 if (get_u8(&nf_call_ip6t, *argv, 0))
325 invarg("invalid nf_call_ip6tables", *argv);
326
327 addattr8(n, 1024, IFLA_BR_NF_CALL_IP6TABLES,
328 nf_call_ip6t);
329 } else if (matches(*argv, "nf_call_arptables") == 0) {
330 __u8 nf_call_arpt;
331
332 NEXT_ARG();
333 if (get_u8(&nf_call_arpt, *argv, 0))
334 invarg("invalid nf_call_arptables", *argv);
335
336 addattr8(n, 1024, IFLA_BR_NF_CALL_ARPTABLES,
337 nf_call_arpt);
338 } else if (matches(*argv, "help") == 0) {
339 explain();
340 return -1;
341 } else {
342 fprintf(stderr, "bridge: unknown command \"%s\"?\n", *argv);
343 explain();
344 return -1;
345 }
346 argc--, argv++;
347 }
348
349 return 0;
350 }
351
352 static void bridge_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb[])
353 {
354 if (!tb)
355 return;
356
357 if (tb[IFLA_BR_FORWARD_DELAY])
358 fprintf(f, "forward_delay %u ",
359 rta_getattr_u32(tb[IFLA_BR_FORWARD_DELAY]));
360
361 if (tb[IFLA_BR_HELLO_TIME])
362 fprintf(f, "hello_time %u ",
363 rta_getattr_u32(tb[IFLA_BR_HELLO_TIME]));
364
365 if (tb[IFLA_BR_MAX_AGE])
366 fprintf(f, "max_age %u ",
367 rta_getattr_u32(tb[IFLA_BR_MAX_AGE]));
368
369 if (tb[IFLA_BR_AGEING_TIME])
370 fprintf(f, "ageing_time %u ",
371 rta_getattr_u32(tb[IFLA_BR_AGEING_TIME]));
372
373 if (tb[IFLA_BR_STP_STATE])
374 fprintf(f, "stp_state %u ",
375 rta_getattr_u32(tb[IFLA_BR_STP_STATE]));
376
377 if (tb[IFLA_BR_PRIORITY])
378 fprintf(f, "priority %u ",
379 rta_getattr_u16(tb[IFLA_BR_PRIORITY]));
380
381 if (tb[IFLA_BR_VLAN_FILTERING])
382 fprintf(f, "vlan_filtering %u ",
383 rta_getattr_u8(tb[IFLA_BR_VLAN_FILTERING]));
384
385 if (tb[IFLA_BR_VLAN_PROTOCOL]) {
386 SPRINT_BUF(b1);
387
388 fprintf(f, "vlan_protocol %s ",
389 ll_proto_n2a(rta_getattr_u16(tb[IFLA_BR_VLAN_PROTOCOL]),
390 b1, sizeof(b1)));
391 }
392
393 if (tb[IFLA_BR_BRIDGE_ID]) {
394 char bridge_id[32];
395
396 br_dump_bridge_id(RTA_DATA(tb[IFLA_BR_BRIDGE_ID]), bridge_id,
397 sizeof(bridge_id));
398 fprintf(f, "bridge_id %s ", bridge_id);
399 }
400
401 if (tb[IFLA_BR_ROOT_ID]) {
402 char root_id[32];
403
404 br_dump_bridge_id(RTA_DATA(tb[IFLA_BR_BRIDGE_ID]), root_id,
405 sizeof(root_id));
406 fprintf(f, "designated_root %s ", root_id);
407 }
408
409 if (tb[IFLA_BR_ROOT_PORT])
410 fprintf(f, "root_port %u ",
411 rta_getattr_u16(tb[IFLA_BR_ROOT_PORT]));
412
413 if (tb[IFLA_BR_ROOT_PATH_COST])
414 fprintf(f, "root_path_cost %u ",
415 rta_getattr_u32(tb[IFLA_BR_ROOT_PATH_COST]));
416
417 if (tb[IFLA_BR_TOPOLOGY_CHANGE])
418 fprintf(f, "topology_change %u ",
419 rta_getattr_u8(tb[IFLA_BR_TOPOLOGY_CHANGE]));
420
421 if (tb[IFLA_BR_TOPOLOGY_CHANGE_DETECTED])
422 fprintf(f, "topology_change_detected %u ",
423 rta_getattr_u8(tb[IFLA_BR_TOPOLOGY_CHANGE_DETECTED]));
424
425 if (tb[IFLA_BR_HELLO_TIMER]) {
426 struct timeval tv;
427
428 __jiffies_to_tv(&tv, rta_getattr_u64(tb[IFLA_BR_HELLO_TIMER]));
429 fprintf(f, "hello_timer %4i.%.2i ", (int)tv.tv_sec,
430 (int)tv.tv_usec/10000);
431 }
432
433 if (tb[IFLA_BR_TCN_TIMER]) {
434 struct timeval tv;
435
436 __jiffies_to_tv(&tv, rta_getattr_u64(tb[IFLA_BR_TCN_TIMER]));
437 fprintf(f, "tcn_timer %4i.%.2i ", (int)tv.tv_sec,
438 (int)tv.tv_usec/10000);
439 }
440
441 if (tb[IFLA_BR_TOPOLOGY_CHANGE_TIMER]) {
442 unsigned long jiffies;
443 struct timeval tv;
444
445 jiffies = rta_getattr_u64(tb[IFLA_BR_TOPOLOGY_CHANGE_TIMER]);
446 __jiffies_to_tv(&tv, jiffies);
447 fprintf(f, "topology_change_timer %4i.%.2i ", (int)tv.tv_sec,
448 (int)tv.tv_usec/10000);
449 }
450
451 if (tb[IFLA_BR_GC_TIMER]) {
452 struct timeval tv;
453
454 __jiffies_to_tv(&tv, rta_getattr_u64(tb[IFLA_BR_GC_TIMER]));
455 fprintf(f, "gc_timer %4i.%.2i ", (int)tv.tv_sec,
456 (int)tv.tv_usec/10000);
457 }
458
459 if (tb[IFLA_BR_VLAN_DEFAULT_PVID])
460 fprintf(f, "vlan_default_pvid %u ",
461 rta_getattr_u16(tb[IFLA_BR_VLAN_DEFAULT_PVID]));
462
463 if (tb[IFLA_BR_VLAN_STATS_ENABLED])
464 fprintf(f, "vlan_stats_enabled %u ",
465 rta_getattr_u8(tb[IFLA_BR_VLAN_STATS_ENABLED]));
466
467 if (tb[IFLA_BR_GROUP_FWD_MASK])
468 fprintf(f, "group_fwd_mask %#x ",
469 rta_getattr_u16(tb[IFLA_BR_GROUP_FWD_MASK]));
470
471 if (tb[IFLA_BR_GROUP_ADDR]) {
472 SPRINT_BUF(mac);
473
474 fprintf(f, "group_address %s ",
475 ll_addr_n2a(RTA_DATA(tb[IFLA_BR_GROUP_ADDR]),
476 RTA_PAYLOAD(tb[IFLA_BR_GROUP_ADDR]),
477 1 /*ARPHDR_ETHER*/, mac, sizeof(mac)));
478 }
479
480 if (tb[IFLA_BR_MCAST_SNOOPING])
481 fprintf(f, "mcast_snooping %u ",
482 rta_getattr_u8(tb[IFLA_BR_MCAST_SNOOPING]));
483
484 if (tb[IFLA_BR_MCAST_ROUTER])
485 fprintf(f, "mcast_router %u ",
486 rta_getattr_u8(tb[IFLA_BR_MCAST_ROUTER]));
487
488 if (tb[IFLA_BR_MCAST_QUERY_USE_IFADDR])
489 fprintf(f, "mcast_query_use_ifaddr %u ",
490 rta_getattr_u8(tb[IFLA_BR_MCAST_QUERY_USE_IFADDR]));
491
492 if (tb[IFLA_BR_MCAST_QUERIER])
493 fprintf(f, "mcast_querier %u ",
494 rta_getattr_u8(tb[IFLA_BR_MCAST_QUERIER]));
495
496 if (tb[IFLA_BR_MCAST_HASH_ELASTICITY])
497 fprintf(f, "mcast_hash_elasticity %u ",
498 rta_getattr_u32(tb[IFLA_BR_MCAST_HASH_ELASTICITY]));
499
500 if (tb[IFLA_BR_MCAST_HASH_MAX])
501 fprintf(f, "mcast_hash_max %u ",
502 rta_getattr_u32(tb[IFLA_BR_MCAST_HASH_MAX]));
503
504 if (tb[IFLA_BR_MCAST_LAST_MEMBER_CNT])
505 fprintf(f, "mcast_last_member_count %u ",
506 rta_getattr_u32(tb[IFLA_BR_MCAST_LAST_MEMBER_CNT]));
507
508 if (tb[IFLA_BR_MCAST_STARTUP_QUERY_CNT])
509 fprintf(f, "mcast_startup_query_count %u ",
510 rta_getattr_u32(tb[IFLA_BR_MCAST_STARTUP_QUERY_CNT]));
511
512 if (tb[IFLA_BR_MCAST_LAST_MEMBER_INTVL])
513 fprintf(f, "mcast_last_member_interval %llu ",
514 rta_getattr_u64(tb[IFLA_BR_MCAST_LAST_MEMBER_INTVL]));
515
516 if (tb[IFLA_BR_MCAST_MEMBERSHIP_INTVL])
517 fprintf(f, "mcast_membership_interval %llu ",
518 rta_getattr_u64(tb[IFLA_BR_MCAST_MEMBERSHIP_INTVL]));
519
520 if (tb[IFLA_BR_MCAST_QUERIER_INTVL])
521 fprintf(f, "mcast_querier_interval %llu ",
522 rta_getattr_u64(tb[IFLA_BR_MCAST_QUERIER_INTVL]));
523
524 if (tb[IFLA_BR_MCAST_QUERY_INTVL])
525 fprintf(f, "mcast_query_interval %llu ",
526 rta_getattr_u64(tb[IFLA_BR_MCAST_QUERY_INTVL]));
527
528 if (tb[IFLA_BR_MCAST_QUERY_RESPONSE_INTVL])
529 fprintf(f, "mcast_query_response_interval %llu ",
530 rta_getattr_u64(tb[IFLA_BR_MCAST_QUERY_RESPONSE_INTVL]));
531
532 if (tb[IFLA_BR_MCAST_STARTUP_QUERY_INTVL])
533 fprintf(f, "mcast_startup_query_interval %llu ",
534 rta_getattr_u64(tb[IFLA_BR_MCAST_STARTUP_QUERY_INTVL]));
535
536 if (tb[IFLA_BR_MCAST_STATS_ENABLED])
537 fprintf(f, "mcast_stats_enabled %u ",
538 rta_getattr_u8(tb[IFLA_BR_MCAST_STATS_ENABLED]));
539
540 if (tb[IFLA_BR_NF_CALL_IPTABLES])
541 fprintf(f, "nf_call_iptables %u ",
542 rta_getattr_u8(tb[IFLA_BR_NF_CALL_IPTABLES]));
543
544 if (tb[IFLA_BR_NF_CALL_IP6TABLES])
545 fprintf(f, "nf_call_ip6tables %u ",
546 rta_getattr_u8(tb[IFLA_BR_NF_CALL_IP6TABLES]));
547
548 if (tb[IFLA_BR_NF_CALL_ARPTABLES])
549 fprintf(f, "nf_call_arptables %u ",
550 rta_getattr_u8(tb[IFLA_BR_NF_CALL_ARPTABLES]));
551 }
552
553 static void bridge_print_help(struct link_util *lu, int argc, char **argv,
554 FILE *f)
555 {
556 print_explain(f);
557 }
558
559 struct link_util bridge_link_util = {
560 .id = "bridge",
561 .maxattr = IFLA_BR_MAX,
562 .parse_opt = bridge_parse_opt,
563 .print_opt = bridge_print_opt,
564 .print_help = bridge_print_help,
565 };