1*de1e4e89SAndroid Build Coastguard Worker /*
2*de1e4e89SAndroid Build Coastguard Worker * iplink_bridge.c Bridge device support
3*de1e4e89SAndroid Build Coastguard Worker *
4*de1e4e89SAndroid Build Coastguard Worker * This program is free software; you can redistribute it and/or
5*de1e4e89SAndroid Build Coastguard Worker * modify it under the terms of the GNU General Public License
6*de1e4e89SAndroid Build Coastguard Worker * as published by the Free Software Foundation; either version
7*de1e4e89SAndroid Build Coastguard Worker * 2 of the License, or (at your option) any later version.
8*de1e4e89SAndroid Build Coastguard Worker *
9*de1e4e89SAndroid Build Coastguard Worker * Authors: Jiri Pirko <[email protected]>
10*de1e4e89SAndroid Build Coastguard Worker */
11*de1e4e89SAndroid Build Coastguard Worker
12*de1e4e89SAndroid Build Coastguard Worker #include <stdio.h>
13*de1e4e89SAndroid Build Coastguard Worker #include <stdlib.h>
14*de1e4e89SAndroid Build Coastguard Worker #include <string.h>
15*de1e4e89SAndroid Build Coastguard Worker #include <netinet/in.h>
16*de1e4e89SAndroid Build Coastguard Worker #include <netinet/ether.h>
17*de1e4e89SAndroid Build Coastguard Worker #include <linux/if_link.h>
18*de1e4e89SAndroid Build Coastguard Worker #include <linux/if_bridge.h>
19*de1e4e89SAndroid Build Coastguard Worker #include <net/if.h>
20*de1e4e89SAndroid Build Coastguard Worker
21*de1e4e89SAndroid Build Coastguard Worker #include "rt_names.h"
22*de1e4e89SAndroid Build Coastguard Worker #include "utils.h"
23*de1e4e89SAndroid Build Coastguard Worker #include "ip_common.h"
24*de1e4e89SAndroid Build Coastguard Worker
25*de1e4e89SAndroid Build Coastguard Worker static unsigned int xstats_print_attr;
26*de1e4e89SAndroid Build Coastguard Worker static int filter_index;
27*de1e4e89SAndroid Build Coastguard Worker
print_explain(FILE * f)28*de1e4e89SAndroid Build Coastguard Worker static void print_explain(FILE *f)
29*de1e4e89SAndroid Build Coastguard Worker {
30*de1e4e89SAndroid Build Coastguard Worker fprintf(f,
31*de1e4e89SAndroid Build Coastguard Worker "Usage: ... bridge [ fdb_flush ]\n"
32*de1e4e89SAndroid Build Coastguard Worker " [ forward_delay FORWARD_DELAY ]\n"
33*de1e4e89SAndroid Build Coastguard Worker " [ hello_time HELLO_TIME ]\n"
34*de1e4e89SAndroid Build Coastguard Worker " [ max_age MAX_AGE ]\n"
35*de1e4e89SAndroid Build Coastguard Worker " [ ageing_time AGEING_TIME ]\n"
36*de1e4e89SAndroid Build Coastguard Worker " [ stp_state STP_STATE ]\n"
37*de1e4e89SAndroid Build Coastguard Worker " [ priority PRIORITY ]\n"
38*de1e4e89SAndroid Build Coastguard Worker " [ group_fwd_mask MASK ]\n"
39*de1e4e89SAndroid Build Coastguard Worker " [ group_address ADDRESS ]\n"
40*de1e4e89SAndroid Build Coastguard Worker " [ vlan_filtering VLAN_FILTERING ]\n"
41*de1e4e89SAndroid Build Coastguard Worker " [ vlan_protocol VLAN_PROTOCOL ]\n"
42*de1e4e89SAndroid Build Coastguard Worker " [ vlan_default_pvid VLAN_DEFAULT_PVID ]\n"
43*de1e4e89SAndroid Build Coastguard Worker " [ vlan_stats_enabled VLAN_STATS_ENABLED ]\n"
44*de1e4e89SAndroid Build Coastguard Worker " [ mcast_snooping MULTICAST_SNOOPING ]\n"
45*de1e4e89SAndroid Build Coastguard Worker " [ mcast_router MULTICAST_ROUTER ]\n"
46*de1e4e89SAndroid Build Coastguard Worker " [ mcast_query_use_ifaddr MCAST_QUERY_USE_IFADDR ]\n"
47*de1e4e89SAndroid Build Coastguard Worker " [ mcast_querier MULTICAST_QUERIER ]\n"
48*de1e4e89SAndroid Build Coastguard Worker " [ mcast_hash_elasticity HASH_ELASTICITY ]\n"
49*de1e4e89SAndroid Build Coastguard Worker " [ mcast_hash_max HASH_MAX ]\n"
50*de1e4e89SAndroid Build Coastguard Worker " [ mcast_last_member_count LAST_MEMBER_COUNT ]\n"
51*de1e4e89SAndroid Build Coastguard Worker " [ mcast_startup_query_count STARTUP_QUERY_COUNT ]\n"
52*de1e4e89SAndroid Build Coastguard Worker " [ mcast_last_member_interval LAST_MEMBER_INTERVAL ]\n"
53*de1e4e89SAndroid Build Coastguard Worker " [ mcast_membership_interval MEMBERSHIP_INTERVAL ]\n"
54*de1e4e89SAndroid Build Coastguard Worker " [ mcast_querier_interval QUERIER_INTERVAL ]\n"
55*de1e4e89SAndroid Build Coastguard Worker " [ mcast_query_interval QUERY_INTERVAL ]\n"
56*de1e4e89SAndroid Build Coastguard Worker " [ mcast_query_response_interval QUERY_RESPONSE_INTERVAL ]\n"
57*de1e4e89SAndroid Build Coastguard Worker " [ mcast_startup_query_interval STARTUP_QUERY_INTERVAL ]\n"
58*de1e4e89SAndroid Build Coastguard Worker " [ mcast_stats_enabled MCAST_STATS_ENABLED ]\n"
59*de1e4e89SAndroid Build Coastguard Worker " [ mcast_igmp_version IGMP_VERSION ]\n"
60*de1e4e89SAndroid Build Coastguard Worker " [ mcast_mld_version MLD_VERSION ]\n"
61*de1e4e89SAndroid Build Coastguard Worker " [ nf_call_iptables NF_CALL_IPTABLES ]\n"
62*de1e4e89SAndroid Build Coastguard Worker " [ nf_call_ip6tables NF_CALL_IP6TABLES ]\n"
63*de1e4e89SAndroid Build Coastguard Worker " [ nf_call_arptables NF_CALL_ARPTABLES ]\n"
64*de1e4e89SAndroid Build Coastguard Worker "\n"
65*de1e4e89SAndroid Build Coastguard Worker "Where: VLAN_PROTOCOL := { 802.1Q | 802.1ad }\n"
66*de1e4e89SAndroid Build Coastguard Worker );
67*de1e4e89SAndroid Build Coastguard Worker }
68*de1e4e89SAndroid Build Coastguard Worker
explain(void)69*de1e4e89SAndroid Build Coastguard Worker static void explain(void)
70*de1e4e89SAndroid Build Coastguard Worker {
71*de1e4e89SAndroid Build Coastguard Worker print_explain(stderr);
72*de1e4e89SAndroid Build Coastguard Worker }
73*de1e4e89SAndroid Build Coastguard Worker
br_dump_bridge_id(const struct ifla_bridge_id * id,char * buf,size_t len)74*de1e4e89SAndroid Build Coastguard Worker void br_dump_bridge_id(const struct ifla_bridge_id *id, char *buf, size_t len)
75*de1e4e89SAndroid Build Coastguard Worker {
76*de1e4e89SAndroid Build Coastguard Worker char eaddr[32];
77*de1e4e89SAndroid Build Coastguard Worker
78*de1e4e89SAndroid Build Coastguard Worker ether_ntoa_r((const struct ether_addr *)id->addr, eaddr);
79*de1e4e89SAndroid Build Coastguard Worker snprintf(buf, len, "%.2x%.2x.%s", id->prio[0], id->prio[1], eaddr);
80*de1e4e89SAndroid Build Coastguard Worker }
81*de1e4e89SAndroid Build Coastguard Worker
bridge_parse_opt(struct link_util * lu,int argc,char ** argv,struct nlmsghdr * n)82*de1e4e89SAndroid Build Coastguard Worker static int bridge_parse_opt(struct link_util *lu, int argc, char **argv,
83*de1e4e89SAndroid Build Coastguard Worker struct nlmsghdr *n)
84*de1e4e89SAndroid Build Coastguard Worker {
85*de1e4e89SAndroid Build Coastguard Worker __u32 val;
86*de1e4e89SAndroid Build Coastguard Worker
87*de1e4e89SAndroid Build Coastguard Worker while (argc > 0) {
88*de1e4e89SAndroid Build Coastguard Worker if (matches(*argv, "forward_delay") == 0) {
89*de1e4e89SAndroid Build Coastguard Worker NEXT_ARG();
90*de1e4e89SAndroid Build Coastguard Worker if (get_u32(&val, *argv, 0))
91*de1e4e89SAndroid Build Coastguard Worker invarg("invalid forward_delay", *argv);
92*de1e4e89SAndroid Build Coastguard Worker
93*de1e4e89SAndroid Build Coastguard Worker addattr32(n, 1024, IFLA_BR_FORWARD_DELAY, val);
94*de1e4e89SAndroid Build Coastguard Worker } else if (matches(*argv, "hello_time") == 0) {
95*de1e4e89SAndroid Build Coastguard Worker NEXT_ARG();
96*de1e4e89SAndroid Build Coastguard Worker if (get_u32(&val, *argv, 0))
97*de1e4e89SAndroid Build Coastguard Worker invarg("invalid hello_time", *argv);
98*de1e4e89SAndroid Build Coastguard Worker
99*de1e4e89SAndroid Build Coastguard Worker addattr32(n, 1024, IFLA_BR_HELLO_TIME, val);
100*de1e4e89SAndroid Build Coastguard Worker } else if (matches(*argv, "max_age") == 0) {
101*de1e4e89SAndroid Build Coastguard Worker NEXT_ARG();
102*de1e4e89SAndroid Build Coastguard Worker if (get_u32(&val, *argv, 0))
103*de1e4e89SAndroid Build Coastguard Worker invarg("invalid max_age", *argv);
104*de1e4e89SAndroid Build Coastguard Worker
105*de1e4e89SAndroid Build Coastguard Worker addattr32(n, 1024, IFLA_BR_MAX_AGE, val);
106*de1e4e89SAndroid Build Coastguard Worker } else if (matches(*argv, "ageing_time") == 0) {
107*de1e4e89SAndroid Build Coastguard Worker NEXT_ARG();
108*de1e4e89SAndroid Build Coastguard Worker if (get_u32(&val, *argv, 0))
109*de1e4e89SAndroid Build Coastguard Worker invarg("invalid ageing_time", *argv);
110*de1e4e89SAndroid Build Coastguard Worker
111*de1e4e89SAndroid Build Coastguard Worker addattr32(n, 1024, IFLA_BR_AGEING_TIME, val);
112*de1e4e89SAndroid Build Coastguard Worker } else if (matches(*argv, "stp_state") == 0) {
113*de1e4e89SAndroid Build Coastguard Worker NEXT_ARG();
114*de1e4e89SAndroid Build Coastguard Worker if (get_u32(&val, *argv, 0))
115*de1e4e89SAndroid Build Coastguard Worker invarg("invalid stp_state", *argv);
116*de1e4e89SAndroid Build Coastguard Worker
117*de1e4e89SAndroid Build Coastguard Worker addattr32(n, 1024, IFLA_BR_STP_STATE, val);
118*de1e4e89SAndroid Build Coastguard Worker } else if (matches(*argv, "priority") == 0) {
119*de1e4e89SAndroid Build Coastguard Worker __u16 prio;
120*de1e4e89SAndroid Build Coastguard Worker
121*de1e4e89SAndroid Build Coastguard Worker NEXT_ARG();
122*de1e4e89SAndroid Build Coastguard Worker if (get_u16(&prio, *argv, 0))
123*de1e4e89SAndroid Build Coastguard Worker invarg("invalid priority", *argv);
124*de1e4e89SAndroid Build Coastguard Worker
125*de1e4e89SAndroid Build Coastguard Worker addattr16(n, 1024, IFLA_BR_PRIORITY, prio);
126*de1e4e89SAndroid Build Coastguard Worker } else if (matches(*argv, "vlan_filtering") == 0) {
127*de1e4e89SAndroid Build Coastguard Worker __u8 vlan_filter;
128*de1e4e89SAndroid Build Coastguard Worker
129*de1e4e89SAndroid Build Coastguard Worker NEXT_ARG();
130*de1e4e89SAndroid Build Coastguard Worker if (get_u8(&vlan_filter, *argv, 0))
131*de1e4e89SAndroid Build Coastguard Worker invarg("invalid vlan_filtering", *argv);
132*de1e4e89SAndroid Build Coastguard Worker
133*de1e4e89SAndroid Build Coastguard Worker addattr8(n, 1024, IFLA_BR_VLAN_FILTERING, vlan_filter);
134*de1e4e89SAndroid Build Coastguard Worker } else if (matches(*argv, "vlan_protocol") == 0) {
135*de1e4e89SAndroid Build Coastguard Worker __u16 vlan_proto;
136*de1e4e89SAndroid Build Coastguard Worker
137*de1e4e89SAndroid Build Coastguard Worker NEXT_ARG();
138*de1e4e89SAndroid Build Coastguard Worker if (ll_proto_a2n(&vlan_proto, *argv))
139*de1e4e89SAndroid Build Coastguard Worker invarg("invalid vlan_protocol", *argv);
140*de1e4e89SAndroid Build Coastguard Worker
141*de1e4e89SAndroid Build Coastguard Worker addattr16(n, 1024, IFLA_BR_VLAN_PROTOCOL, vlan_proto);
142*de1e4e89SAndroid Build Coastguard Worker } else if (matches(*argv, "group_fwd_mask") == 0) {
143*de1e4e89SAndroid Build Coastguard Worker __u16 fwd_mask;
144*de1e4e89SAndroid Build Coastguard Worker
145*de1e4e89SAndroid Build Coastguard Worker NEXT_ARG();
146*de1e4e89SAndroid Build Coastguard Worker if (get_u16(&fwd_mask, *argv, 0))
147*de1e4e89SAndroid Build Coastguard Worker invarg("invalid group_fwd_mask", *argv);
148*de1e4e89SAndroid Build Coastguard Worker
149*de1e4e89SAndroid Build Coastguard Worker addattr16(n, 1024, IFLA_BR_GROUP_FWD_MASK, fwd_mask);
150*de1e4e89SAndroid Build Coastguard Worker } else if (matches(*argv, "group_address") == 0) {
151*de1e4e89SAndroid Build Coastguard Worker char llabuf[32];
152*de1e4e89SAndroid Build Coastguard Worker int len;
153*de1e4e89SAndroid Build Coastguard Worker
154*de1e4e89SAndroid Build Coastguard Worker NEXT_ARG();
155*de1e4e89SAndroid Build Coastguard Worker len = ll_addr_a2n(llabuf, sizeof(llabuf), *argv);
156*de1e4e89SAndroid Build Coastguard Worker if (len < 0)
157*de1e4e89SAndroid Build Coastguard Worker return -1;
158*de1e4e89SAndroid Build Coastguard Worker addattr_l(n, 1024, IFLA_BR_GROUP_ADDR, llabuf, len);
159*de1e4e89SAndroid Build Coastguard Worker } else if (matches(*argv, "fdb_flush") == 0) {
160*de1e4e89SAndroid Build Coastguard Worker addattr(n, 1024, IFLA_BR_FDB_FLUSH);
161*de1e4e89SAndroid Build Coastguard Worker } else if (matches(*argv, "vlan_default_pvid") == 0) {
162*de1e4e89SAndroid Build Coastguard Worker __u16 default_pvid;
163*de1e4e89SAndroid Build Coastguard Worker
164*de1e4e89SAndroid Build Coastguard Worker NEXT_ARG();
165*de1e4e89SAndroid Build Coastguard Worker if (get_u16(&default_pvid, *argv, 0))
166*de1e4e89SAndroid Build Coastguard Worker invarg("invalid vlan_default_pvid", *argv);
167*de1e4e89SAndroid Build Coastguard Worker
168*de1e4e89SAndroid Build Coastguard Worker addattr16(n, 1024, IFLA_BR_VLAN_DEFAULT_PVID,
169*de1e4e89SAndroid Build Coastguard Worker default_pvid);
170*de1e4e89SAndroid Build Coastguard Worker } else if (matches(*argv, "vlan_stats_enabled") == 0) {
171*de1e4e89SAndroid Build Coastguard Worker __u8 vlan_stats_enabled;
172*de1e4e89SAndroid Build Coastguard Worker
173*de1e4e89SAndroid Build Coastguard Worker NEXT_ARG();
174*de1e4e89SAndroid Build Coastguard Worker if (get_u8(&vlan_stats_enabled, *argv, 0))
175*de1e4e89SAndroid Build Coastguard Worker invarg("invalid vlan_stats_enabled", *argv);
176*de1e4e89SAndroid Build Coastguard Worker addattr8(n, 1024, IFLA_BR_VLAN_STATS_ENABLED,
177*de1e4e89SAndroid Build Coastguard Worker vlan_stats_enabled);
178*de1e4e89SAndroid Build Coastguard Worker } else if (matches(*argv, "mcast_router") == 0) {
179*de1e4e89SAndroid Build Coastguard Worker __u8 mcast_router;
180*de1e4e89SAndroid Build Coastguard Worker
181*de1e4e89SAndroid Build Coastguard Worker NEXT_ARG();
182*de1e4e89SAndroid Build Coastguard Worker if (get_u8(&mcast_router, *argv, 0))
183*de1e4e89SAndroid Build Coastguard Worker invarg("invalid mcast_router", *argv);
184*de1e4e89SAndroid Build Coastguard Worker
185*de1e4e89SAndroid Build Coastguard Worker addattr8(n, 1024, IFLA_BR_MCAST_ROUTER, mcast_router);
186*de1e4e89SAndroid Build Coastguard Worker } else if (matches(*argv, "mcast_snooping") == 0) {
187*de1e4e89SAndroid Build Coastguard Worker __u8 mcast_snoop;
188*de1e4e89SAndroid Build Coastguard Worker
189*de1e4e89SAndroid Build Coastguard Worker NEXT_ARG();
190*de1e4e89SAndroid Build Coastguard Worker if (get_u8(&mcast_snoop, *argv, 0))
191*de1e4e89SAndroid Build Coastguard Worker invarg("invalid mcast_snooping", *argv);
192*de1e4e89SAndroid Build Coastguard Worker
193*de1e4e89SAndroid Build Coastguard Worker addattr8(n, 1024, IFLA_BR_MCAST_SNOOPING, mcast_snoop);
194*de1e4e89SAndroid Build Coastguard Worker } else if (matches(*argv, "mcast_query_use_ifaddr") == 0) {
195*de1e4e89SAndroid Build Coastguard Worker __u8 mcast_qui;
196*de1e4e89SAndroid Build Coastguard Worker
197*de1e4e89SAndroid Build Coastguard Worker NEXT_ARG();
198*de1e4e89SAndroid Build Coastguard Worker if (get_u8(&mcast_qui, *argv, 0))
199*de1e4e89SAndroid Build Coastguard Worker invarg("invalid mcast_query_use_ifaddr",
200*de1e4e89SAndroid Build Coastguard Worker *argv);
201*de1e4e89SAndroid Build Coastguard Worker
202*de1e4e89SAndroid Build Coastguard Worker addattr8(n, 1024, IFLA_BR_MCAST_QUERY_USE_IFADDR,
203*de1e4e89SAndroid Build Coastguard Worker mcast_qui);
204*de1e4e89SAndroid Build Coastguard Worker } else if (matches(*argv, "mcast_querier") == 0) {
205*de1e4e89SAndroid Build Coastguard Worker __u8 mcast_querier;
206*de1e4e89SAndroid Build Coastguard Worker
207*de1e4e89SAndroid Build Coastguard Worker NEXT_ARG();
208*de1e4e89SAndroid Build Coastguard Worker if (get_u8(&mcast_querier, *argv, 0))
209*de1e4e89SAndroid Build Coastguard Worker invarg("invalid mcast_querier", *argv);
210*de1e4e89SAndroid Build Coastguard Worker
211*de1e4e89SAndroid Build Coastguard Worker addattr8(n, 1024, IFLA_BR_MCAST_QUERIER, mcast_querier);
212*de1e4e89SAndroid Build Coastguard Worker } else if (matches(*argv, "mcast_hash_elasticity") == 0) {
213*de1e4e89SAndroid Build Coastguard Worker __u32 mcast_hash_el;
214*de1e4e89SAndroid Build Coastguard Worker
215*de1e4e89SAndroid Build Coastguard Worker NEXT_ARG();
216*de1e4e89SAndroid Build Coastguard Worker if (get_u32(&mcast_hash_el, *argv, 0))
217*de1e4e89SAndroid Build Coastguard Worker invarg("invalid mcast_hash_elasticity",
218*de1e4e89SAndroid Build Coastguard Worker *argv);
219*de1e4e89SAndroid Build Coastguard Worker
220*de1e4e89SAndroid Build Coastguard Worker addattr32(n, 1024, IFLA_BR_MCAST_HASH_ELASTICITY,
221*de1e4e89SAndroid Build Coastguard Worker mcast_hash_el);
222*de1e4e89SAndroid Build Coastguard Worker } else if (matches(*argv, "mcast_hash_max") == 0) {
223*de1e4e89SAndroid Build Coastguard Worker __u32 mcast_hash_max;
224*de1e4e89SAndroid Build Coastguard Worker
225*de1e4e89SAndroid Build Coastguard Worker NEXT_ARG();
226*de1e4e89SAndroid Build Coastguard Worker if (get_u32(&mcast_hash_max, *argv, 0))
227*de1e4e89SAndroid Build Coastguard Worker invarg("invalid mcast_hash_max", *argv);
228*de1e4e89SAndroid Build Coastguard Worker
229*de1e4e89SAndroid Build Coastguard Worker addattr32(n, 1024, IFLA_BR_MCAST_HASH_MAX,
230*de1e4e89SAndroid Build Coastguard Worker mcast_hash_max);
231*de1e4e89SAndroid Build Coastguard Worker } else if (matches(*argv, "mcast_last_member_count") == 0) {
232*de1e4e89SAndroid Build Coastguard Worker __u32 mcast_lmc;
233*de1e4e89SAndroid Build Coastguard Worker
234*de1e4e89SAndroid Build Coastguard Worker NEXT_ARG();
235*de1e4e89SAndroid Build Coastguard Worker if (get_u32(&mcast_lmc, *argv, 0))
236*de1e4e89SAndroid Build Coastguard Worker invarg("invalid mcast_last_member_count",
237*de1e4e89SAndroid Build Coastguard Worker *argv);
238*de1e4e89SAndroid Build Coastguard Worker
239*de1e4e89SAndroid Build Coastguard Worker addattr32(n, 1024, IFLA_BR_MCAST_LAST_MEMBER_CNT,
240*de1e4e89SAndroid Build Coastguard Worker mcast_lmc);
241*de1e4e89SAndroid Build Coastguard Worker } else if (matches(*argv, "mcast_startup_query_count") == 0) {
242*de1e4e89SAndroid Build Coastguard Worker __u32 mcast_sqc;
243*de1e4e89SAndroid Build Coastguard Worker
244*de1e4e89SAndroid Build Coastguard Worker NEXT_ARG();
245*de1e4e89SAndroid Build Coastguard Worker if (get_u32(&mcast_sqc, *argv, 0))
246*de1e4e89SAndroid Build Coastguard Worker invarg("invalid mcast_startup_query_count",
247*de1e4e89SAndroid Build Coastguard Worker *argv);
248*de1e4e89SAndroid Build Coastguard Worker
249*de1e4e89SAndroid Build Coastguard Worker addattr32(n, 1024, IFLA_BR_MCAST_STARTUP_QUERY_CNT,
250*de1e4e89SAndroid Build Coastguard Worker mcast_sqc);
251*de1e4e89SAndroid Build Coastguard Worker } else if (matches(*argv, "mcast_last_member_interval") == 0) {
252*de1e4e89SAndroid Build Coastguard Worker __u64 mcast_last_member_intvl;
253*de1e4e89SAndroid Build Coastguard Worker
254*de1e4e89SAndroid Build Coastguard Worker NEXT_ARG();
255*de1e4e89SAndroid Build Coastguard Worker if (get_u64(&mcast_last_member_intvl, *argv, 0))
256*de1e4e89SAndroid Build Coastguard Worker invarg("invalid mcast_last_member_interval",
257*de1e4e89SAndroid Build Coastguard Worker *argv);
258*de1e4e89SAndroid Build Coastguard Worker
259*de1e4e89SAndroid Build Coastguard Worker addattr64(n, 1024, IFLA_BR_MCAST_LAST_MEMBER_INTVL,
260*de1e4e89SAndroid Build Coastguard Worker mcast_last_member_intvl);
261*de1e4e89SAndroid Build Coastguard Worker } else if (matches(*argv, "mcast_membership_interval") == 0) {
262*de1e4e89SAndroid Build Coastguard Worker __u64 mcast_membership_intvl;
263*de1e4e89SAndroid Build Coastguard Worker
264*de1e4e89SAndroid Build Coastguard Worker NEXT_ARG();
265*de1e4e89SAndroid Build Coastguard Worker if (get_u64(&mcast_membership_intvl, *argv, 0))
266*de1e4e89SAndroid Build Coastguard Worker invarg("invalid mcast_membership_interval",
267*de1e4e89SAndroid Build Coastguard Worker *argv);
268*de1e4e89SAndroid Build Coastguard Worker
269*de1e4e89SAndroid Build Coastguard Worker addattr64(n, 1024, IFLA_BR_MCAST_MEMBERSHIP_INTVL,
270*de1e4e89SAndroid Build Coastguard Worker mcast_membership_intvl);
271*de1e4e89SAndroid Build Coastguard Worker } else if (matches(*argv, "mcast_querier_interval") == 0) {
272*de1e4e89SAndroid Build Coastguard Worker __u64 mcast_querier_intvl;
273*de1e4e89SAndroid Build Coastguard Worker
274*de1e4e89SAndroid Build Coastguard Worker NEXT_ARG();
275*de1e4e89SAndroid Build Coastguard Worker if (get_u64(&mcast_querier_intvl, *argv, 0))
276*de1e4e89SAndroid Build Coastguard Worker invarg("invalid mcast_querier_interval",
277*de1e4e89SAndroid Build Coastguard Worker *argv);
278*de1e4e89SAndroid Build Coastguard Worker
279*de1e4e89SAndroid Build Coastguard Worker addattr64(n, 1024, IFLA_BR_MCAST_QUERIER_INTVL,
280*de1e4e89SAndroid Build Coastguard Worker mcast_querier_intvl);
281*de1e4e89SAndroid Build Coastguard Worker } else if (matches(*argv, "mcast_query_interval") == 0) {
282*de1e4e89SAndroid Build Coastguard Worker __u64 mcast_query_intvl;
283*de1e4e89SAndroid Build Coastguard Worker
284*de1e4e89SAndroid Build Coastguard Worker NEXT_ARG();
285*de1e4e89SAndroid Build Coastguard Worker if (get_u64(&mcast_query_intvl, *argv, 0))
286*de1e4e89SAndroid Build Coastguard Worker invarg("invalid mcast_query_interval",
287*de1e4e89SAndroid Build Coastguard Worker *argv);
288*de1e4e89SAndroid Build Coastguard Worker
289*de1e4e89SAndroid Build Coastguard Worker addattr64(n, 1024, IFLA_BR_MCAST_QUERY_INTVL,
290*de1e4e89SAndroid Build Coastguard Worker mcast_query_intvl);
291*de1e4e89SAndroid Build Coastguard Worker } else if (!matches(*argv, "mcast_query_response_interval")) {
292*de1e4e89SAndroid Build Coastguard Worker __u64 mcast_query_resp_intvl;
293*de1e4e89SAndroid Build Coastguard Worker
294*de1e4e89SAndroid Build Coastguard Worker NEXT_ARG();
295*de1e4e89SAndroid Build Coastguard Worker if (get_u64(&mcast_query_resp_intvl, *argv, 0))
296*de1e4e89SAndroid Build Coastguard Worker invarg("invalid mcast_query_response_interval",
297*de1e4e89SAndroid Build Coastguard Worker *argv);
298*de1e4e89SAndroid Build Coastguard Worker
299*de1e4e89SAndroid Build Coastguard Worker addattr64(n, 1024, IFLA_BR_MCAST_QUERY_RESPONSE_INTVL,
300*de1e4e89SAndroid Build Coastguard Worker mcast_query_resp_intvl);
301*de1e4e89SAndroid Build Coastguard Worker } else if (!matches(*argv, "mcast_startup_query_interval")) {
302*de1e4e89SAndroid Build Coastguard Worker __u64 mcast_startup_query_intvl;
303*de1e4e89SAndroid Build Coastguard Worker
304*de1e4e89SAndroid Build Coastguard Worker NEXT_ARG();
305*de1e4e89SAndroid Build Coastguard Worker if (get_u64(&mcast_startup_query_intvl, *argv, 0))
306*de1e4e89SAndroid Build Coastguard Worker invarg("invalid mcast_startup_query_interval",
307*de1e4e89SAndroid Build Coastguard Worker *argv);
308*de1e4e89SAndroid Build Coastguard Worker
309*de1e4e89SAndroid Build Coastguard Worker addattr64(n, 1024, IFLA_BR_MCAST_STARTUP_QUERY_INTVL,
310*de1e4e89SAndroid Build Coastguard Worker mcast_startup_query_intvl);
311*de1e4e89SAndroid Build Coastguard Worker } else if (matches(*argv, "mcast_stats_enabled") == 0) {
312*de1e4e89SAndroid Build Coastguard Worker __u8 mcast_stats_enabled;
313*de1e4e89SAndroid Build Coastguard Worker
314*de1e4e89SAndroid Build Coastguard Worker NEXT_ARG();
315*de1e4e89SAndroid Build Coastguard Worker if (get_u8(&mcast_stats_enabled, *argv, 0))
316*de1e4e89SAndroid Build Coastguard Worker invarg("invalid mcast_stats_enabled", *argv);
317*de1e4e89SAndroid Build Coastguard Worker addattr8(n, 1024, IFLA_BR_MCAST_STATS_ENABLED,
318*de1e4e89SAndroid Build Coastguard Worker mcast_stats_enabled);
319*de1e4e89SAndroid Build Coastguard Worker } else if (matches(*argv, "mcast_igmp_version") == 0) {
320*de1e4e89SAndroid Build Coastguard Worker __u8 igmp_version;
321*de1e4e89SAndroid Build Coastguard Worker
322*de1e4e89SAndroid Build Coastguard Worker NEXT_ARG();
323*de1e4e89SAndroid Build Coastguard Worker if (get_u8(&igmp_version, *argv, 0))
324*de1e4e89SAndroid Build Coastguard Worker invarg("invalid mcast_igmp_version", *argv);
325*de1e4e89SAndroid Build Coastguard Worker addattr8(n, 1024, IFLA_BR_MCAST_IGMP_VERSION,
326*de1e4e89SAndroid Build Coastguard Worker igmp_version);
327*de1e4e89SAndroid Build Coastguard Worker } else if (matches(*argv, "mcast_mld_version") == 0) {
328*de1e4e89SAndroid Build Coastguard Worker __u8 mld_version;
329*de1e4e89SAndroid Build Coastguard Worker
330*de1e4e89SAndroid Build Coastguard Worker NEXT_ARG();
331*de1e4e89SAndroid Build Coastguard Worker if (get_u8(&mld_version, *argv, 0))
332*de1e4e89SAndroid Build Coastguard Worker invarg("invalid mcast_mld_version", *argv);
333*de1e4e89SAndroid Build Coastguard Worker addattr8(n, 1024, IFLA_BR_MCAST_MLD_VERSION,
334*de1e4e89SAndroid Build Coastguard Worker mld_version);
335*de1e4e89SAndroid Build Coastguard Worker } else if (matches(*argv, "nf_call_iptables") == 0) {
336*de1e4e89SAndroid Build Coastguard Worker __u8 nf_call_ipt;
337*de1e4e89SAndroid Build Coastguard Worker
338*de1e4e89SAndroid Build Coastguard Worker NEXT_ARG();
339*de1e4e89SAndroid Build Coastguard Worker if (get_u8(&nf_call_ipt, *argv, 0))
340*de1e4e89SAndroid Build Coastguard Worker invarg("invalid nf_call_iptables", *argv);
341*de1e4e89SAndroid Build Coastguard Worker
342*de1e4e89SAndroid Build Coastguard Worker addattr8(n, 1024, IFLA_BR_NF_CALL_IPTABLES,
343*de1e4e89SAndroid Build Coastguard Worker nf_call_ipt);
344*de1e4e89SAndroid Build Coastguard Worker } else if (matches(*argv, "nf_call_ip6tables") == 0) {
345*de1e4e89SAndroid Build Coastguard Worker __u8 nf_call_ip6t;
346*de1e4e89SAndroid Build Coastguard Worker
347*de1e4e89SAndroid Build Coastguard Worker NEXT_ARG();
348*de1e4e89SAndroid Build Coastguard Worker if (get_u8(&nf_call_ip6t, *argv, 0))
349*de1e4e89SAndroid Build Coastguard Worker invarg("invalid nf_call_ip6tables", *argv);
350*de1e4e89SAndroid Build Coastguard Worker
351*de1e4e89SAndroid Build Coastguard Worker addattr8(n, 1024, IFLA_BR_NF_CALL_IP6TABLES,
352*de1e4e89SAndroid Build Coastguard Worker nf_call_ip6t);
353*de1e4e89SAndroid Build Coastguard Worker } else if (matches(*argv, "nf_call_arptables") == 0) {
354*de1e4e89SAndroid Build Coastguard Worker __u8 nf_call_arpt;
355*de1e4e89SAndroid Build Coastguard Worker
356*de1e4e89SAndroid Build Coastguard Worker NEXT_ARG();
357*de1e4e89SAndroid Build Coastguard Worker if (get_u8(&nf_call_arpt, *argv, 0))
358*de1e4e89SAndroid Build Coastguard Worker invarg("invalid nf_call_arptables", *argv);
359*de1e4e89SAndroid Build Coastguard Worker
360*de1e4e89SAndroid Build Coastguard Worker addattr8(n, 1024, IFLA_BR_NF_CALL_ARPTABLES,
361*de1e4e89SAndroid Build Coastguard Worker nf_call_arpt);
362*de1e4e89SAndroid Build Coastguard Worker } else if (matches(*argv, "help") == 0) {
363*de1e4e89SAndroid Build Coastguard Worker explain();
364*de1e4e89SAndroid Build Coastguard Worker return -1;
365*de1e4e89SAndroid Build Coastguard Worker } else {
366*de1e4e89SAndroid Build Coastguard Worker fprintf(stderr, "bridge: unknown command \"%s\"?\n", *argv);
367*de1e4e89SAndroid Build Coastguard Worker explain();
368*de1e4e89SAndroid Build Coastguard Worker return -1;
369*de1e4e89SAndroid Build Coastguard Worker }
370*de1e4e89SAndroid Build Coastguard Worker argc--, argv++;
371*de1e4e89SAndroid Build Coastguard Worker }
372*de1e4e89SAndroid Build Coastguard Worker
373*de1e4e89SAndroid Build Coastguard Worker return 0;
374*de1e4e89SAndroid Build Coastguard Worker }
375*de1e4e89SAndroid Build Coastguard Worker
_bridge_print_timer(FILE * f,const char * attr,struct rtattr * timer)376*de1e4e89SAndroid Build Coastguard Worker static void _bridge_print_timer(FILE *f,
377*de1e4e89SAndroid Build Coastguard Worker const char *attr,
378*de1e4e89SAndroid Build Coastguard Worker struct rtattr *timer)
379*de1e4e89SAndroid Build Coastguard Worker {
380*de1e4e89SAndroid Build Coastguard Worker struct timeval tv;
381*de1e4e89SAndroid Build Coastguard Worker
382*de1e4e89SAndroid Build Coastguard Worker __jiffies_to_tv(&tv, rta_getattr_u64(timer));
383*de1e4e89SAndroid Build Coastguard Worker if (is_json_context()) {
384*de1e4e89SAndroid Build Coastguard Worker json_writer_t *jw = get_json_writer();
385*de1e4e89SAndroid Build Coastguard Worker
386*de1e4e89SAndroid Build Coastguard Worker jsonw_name(jw, attr);
387*de1e4e89SAndroid Build Coastguard Worker jsonw_printf(jw, "%i.%.2i",
388*de1e4e89SAndroid Build Coastguard Worker (int)tv.tv_sec,
389*de1e4e89SAndroid Build Coastguard Worker (int)tv.tv_usec / 10000);
390*de1e4e89SAndroid Build Coastguard Worker } else {
391*de1e4e89SAndroid Build Coastguard Worker fprintf(f, "%s %4i.%.2i ", attr, (int)tv.tv_sec,
392*de1e4e89SAndroid Build Coastguard Worker (int)tv.tv_usec / 10000);
393*de1e4e89SAndroid Build Coastguard Worker }
394*de1e4e89SAndroid Build Coastguard Worker }
395*de1e4e89SAndroid Build Coastguard Worker
bridge_print_opt(struct link_util * lu,FILE * f,struct rtattr * tb[])396*de1e4e89SAndroid Build Coastguard Worker static void bridge_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb[])
397*de1e4e89SAndroid Build Coastguard Worker {
398*de1e4e89SAndroid Build Coastguard Worker if (!tb)
399*de1e4e89SAndroid Build Coastguard Worker return;
400*de1e4e89SAndroid Build Coastguard Worker
401*de1e4e89SAndroid Build Coastguard Worker if (tb[IFLA_BR_FORWARD_DELAY])
402*de1e4e89SAndroid Build Coastguard Worker print_uint(PRINT_ANY,
403*de1e4e89SAndroid Build Coastguard Worker "forward_delay",
404*de1e4e89SAndroid Build Coastguard Worker "forward_delay %u ",
405*de1e4e89SAndroid Build Coastguard Worker rta_getattr_u32(tb[IFLA_BR_FORWARD_DELAY]));
406*de1e4e89SAndroid Build Coastguard Worker
407*de1e4e89SAndroid Build Coastguard Worker if (tb[IFLA_BR_HELLO_TIME])
408*de1e4e89SAndroid Build Coastguard Worker print_uint(PRINT_ANY,
409*de1e4e89SAndroid Build Coastguard Worker "hello_time",
410*de1e4e89SAndroid Build Coastguard Worker "hello_time %u ",
411*de1e4e89SAndroid Build Coastguard Worker rta_getattr_u32(tb[IFLA_BR_HELLO_TIME]));
412*de1e4e89SAndroid Build Coastguard Worker
413*de1e4e89SAndroid Build Coastguard Worker if (tb[IFLA_BR_MAX_AGE])
414*de1e4e89SAndroid Build Coastguard Worker print_uint(PRINT_ANY,
415*de1e4e89SAndroid Build Coastguard Worker "max_age",
416*de1e4e89SAndroid Build Coastguard Worker "max_age %u ",
417*de1e4e89SAndroid Build Coastguard Worker rta_getattr_u32(tb[IFLA_BR_MAX_AGE]));
418*de1e4e89SAndroid Build Coastguard Worker
419*de1e4e89SAndroid Build Coastguard Worker if (tb[IFLA_BR_AGEING_TIME])
420*de1e4e89SAndroid Build Coastguard Worker print_uint(PRINT_ANY,
421*de1e4e89SAndroid Build Coastguard Worker "ageing_time",
422*de1e4e89SAndroid Build Coastguard Worker "ageing_time %u ",
423*de1e4e89SAndroid Build Coastguard Worker rta_getattr_u32(tb[IFLA_BR_AGEING_TIME]));
424*de1e4e89SAndroid Build Coastguard Worker
425*de1e4e89SAndroid Build Coastguard Worker if (tb[IFLA_BR_STP_STATE])
426*de1e4e89SAndroid Build Coastguard Worker print_uint(PRINT_ANY,
427*de1e4e89SAndroid Build Coastguard Worker "stp_state",
428*de1e4e89SAndroid Build Coastguard Worker "stp_state %u ",
429*de1e4e89SAndroid Build Coastguard Worker rta_getattr_u32(tb[IFLA_BR_STP_STATE]));
430*de1e4e89SAndroid Build Coastguard Worker
431*de1e4e89SAndroid Build Coastguard Worker if (tb[IFLA_BR_PRIORITY])
432*de1e4e89SAndroid Build Coastguard Worker print_uint(PRINT_ANY,
433*de1e4e89SAndroid Build Coastguard Worker "priority",
434*de1e4e89SAndroid Build Coastguard Worker "priority %u ",
435*de1e4e89SAndroid Build Coastguard Worker rta_getattr_u16(tb[IFLA_BR_PRIORITY]));
436*de1e4e89SAndroid Build Coastguard Worker
437*de1e4e89SAndroid Build Coastguard Worker if (tb[IFLA_BR_VLAN_FILTERING])
438*de1e4e89SAndroid Build Coastguard Worker print_uint(PRINT_ANY,
439*de1e4e89SAndroid Build Coastguard Worker "vlan_filtering",
440*de1e4e89SAndroid Build Coastguard Worker "vlan_filtering %u ",
441*de1e4e89SAndroid Build Coastguard Worker rta_getattr_u8(tb[IFLA_BR_VLAN_FILTERING]));
442*de1e4e89SAndroid Build Coastguard Worker
443*de1e4e89SAndroid Build Coastguard Worker if (tb[IFLA_BR_VLAN_PROTOCOL]) {
444*de1e4e89SAndroid Build Coastguard Worker SPRINT_BUF(b1);
445*de1e4e89SAndroid Build Coastguard Worker
446*de1e4e89SAndroid Build Coastguard Worker print_string(PRINT_ANY,
447*de1e4e89SAndroid Build Coastguard Worker "vlan_protocol",
448*de1e4e89SAndroid Build Coastguard Worker "vlan_protocol %s ",
449*de1e4e89SAndroid Build Coastguard Worker ll_proto_n2a(rta_getattr_u16(tb[IFLA_BR_VLAN_PROTOCOL]),
450*de1e4e89SAndroid Build Coastguard Worker b1, sizeof(b1)));
451*de1e4e89SAndroid Build Coastguard Worker }
452*de1e4e89SAndroid Build Coastguard Worker
453*de1e4e89SAndroid Build Coastguard Worker if (tb[IFLA_BR_BRIDGE_ID]) {
454*de1e4e89SAndroid Build Coastguard Worker char bridge_id[32];
455*de1e4e89SAndroid Build Coastguard Worker
456*de1e4e89SAndroid Build Coastguard Worker br_dump_bridge_id(RTA_DATA(tb[IFLA_BR_BRIDGE_ID]), bridge_id,
457*de1e4e89SAndroid Build Coastguard Worker sizeof(bridge_id));
458*de1e4e89SAndroid Build Coastguard Worker print_string(PRINT_ANY,
459*de1e4e89SAndroid Build Coastguard Worker "bridge_id",
460*de1e4e89SAndroid Build Coastguard Worker "bridge_id %s ",
461*de1e4e89SAndroid Build Coastguard Worker bridge_id);
462*de1e4e89SAndroid Build Coastguard Worker }
463*de1e4e89SAndroid Build Coastguard Worker
464*de1e4e89SAndroid Build Coastguard Worker if (tb[IFLA_BR_ROOT_ID]) {
465*de1e4e89SAndroid Build Coastguard Worker char root_id[32];
466*de1e4e89SAndroid Build Coastguard Worker
467*de1e4e89SAndroid Build Coastguard Worker br_dump_bridge_id(RTA_DATA(tb[IFLA_BR_BRIDGE_ID]), root_id,
468*de1e4e89SAndroid Build Coastguard Worker sizeof(root_id));
469*de1e4e89SAndroid Build Coastguard Worker print_string(PRINT_ANY,
470*de1e4e89SAndroid Build Coastguard Worker "root_id",
471*de1e4e89SAndroid Build Coastguard Worker "designated_root %s ",
472*de1e4e89SAndroid Build Coastguard Worker root_id);
473*de1e4e89SAndroid Build Coastguard Worker }
474*de1e4e89SAndroid Build Coastguard Worker
475*de1e4e89SAndroid Build Coastguard Worker if (tb[IFLA_BR_ROOT_PORT])
476*de1e4e89SAndroid Build Coastguard Worker print_uint(PRINT_ANY,
477*de1e4e89SAndroid Build Coastguard Worker "root_port",
478*de1e4e89SAndroid Build Coastguard Worker "root_port %u ",
479*de1e4e89SAndroid Build Coastguard Worker rta_getattr_u16(tb[IFLA_BR_ROOT_PORT]));
480*de1e4e89SAndroid Build Coastguard Worker
481*de1e4e89SAndroid Build Coastguard Worker if (tb[IFLA_BR_ROOT_PATH_COST])
482*de1e4e89SAndroid Build Coastguard Worker print_uint(PRINT_ANY,
483*de1e4e89SAndroid Build Coastguard Worker "root_path_cost",
484*de1e4e89SAndroid Build Coastguard Worker "root_path_cost %u ",
485*de1e4e89SAndroid Build Coastguard Worker rta_getattr_u32(tb[IFLA_BR_ROOT_PATH_COST]));
486*de1e4e89SAndroid Build Coastguard Worker
487*de1e4e89SAndroid Build Coastguard Worker if (tb[IFLA_BR_TOPOLOGY_CHANGE])
488*de1e4e89SAndroid Build Coastguard Worker print_uint(PRINT_ANY,
489*de1e4e89SAndroid Build Coastguard Worker "topology_change",
490*de1e4e89SAndroid Build Coastguard Worker "topology_change %u ",
491*de1e4e89SAndroid Build Coastguard Worker rta_getattr_u8(tb[IFLA_BR_TOPOLOGY_CHANGE]));
492*de1e4e89SAndroid Build Coastguard Worker
493*de1e4e89SAndroid Build Coastguard Worker if (tb[IFLA_BR_TOPOLOGY_CHANGE_DETECTED])
494*de1e4e89SAndroid Build Coastguard Worker print_uint(PRINT_ANY,
495*de1e4e89SAndroid Build Coastguard Worker "topology_change_detected",
496*de1e4e89SAndroid Build Coastguard Worker "topology_change_detected %u ",
497*de1e4e89SAndroid Build Coastguard Worker rta_getattr_u8(tb[IFLA_BR_TOPOLOGY_CHANGE_DETECTED]));
498*de1e4e89SAndroid Build Coastguard Worker
499*de1e4e89SAndroid Build Coastguard Worker if (tb[IFLA_BR_HELLO_TIMER])
500*de1e4e89SAndroid Build Coastguard Worker _bridge_print_timer(f, "hello_timer", tb[IFLA_BR_HELLO_TIMER]);
501*de1e4e89SAndroid Build Coastguard Worker
502*de1e4e89SAndroid Build Coastguard Worker if (tb[IFLA_BR_TCN_TIMER])
503*de1e4e89SAndroid Build Coastguard Worker _bridge_print_timer(f, "tcn_timer", tb[IFLA_BR_TCN_TIMER]);
504*de1e4e89SAndroid Build Coastguard Worker
505*de1e4e89SAndroid Build Coastguard Worker if (tb[IFLA_BR_TOPOLOGY_CHANGE_TIMER])
506*de1e4e89SAndroid Build Coastguard Worker _bridge_print_timer(f, "topology_change_timer",
507*de1e4e89SAndroid Build Coastguard Worker tb[IFLA_BR_TOPOLOGY_CHANGE_TIMER]);
508*de1e4e89SAndroid Build Coastguard Worker
509*de1e4e89SAndroid Build Coastguard Worker if (tb[IFLA_BR_GC_TIMER])
510*de1e4e89SAndroid Build Coastguard Worker _bridge_print_timer(f, "gc_timer", tb[IFLA_BR_GC_TIMER]);
511*de1e4e89SAndroid Build Coastguard Worker
512*de1e4e89SAndroid Build Coastguard Worker if (tb[IFLA_BR_VLAN_DEFAULT_PVID])
513*de1e4e89SAndroid Build Coastguard Worker print_uint(PRINT_ANY,
514*de1e4e89SAndroid Build Coastguard Worker "vlan_default_pvid",
515*de1e4e89SAndroid Build Coastguard Worker "vlan_default_pvid %u ",
516*de1e4e89SAndroid Build Coastguard Worker rta_getattr_u16(tb[IFLA_BR_VLAN_DEFAULT_PVID]));
517*de1e4e89SAndroid Build Coastguard Worker
518*de1e4e89SAndroid Build Coastguard Worker if (tb[IFLA_BR_VLAN_STATS_ENABLED])
519*de1e4e89SAndroid Build Coastguard Worker print_uint(PRINT_ANY,
520*de1e4e89SAndroid Build Coastguard Worker "vlan_stats_enabled",
521*de1e4e89SAndroid Build Coastguard Worker "vlan_stats_enabled %u ",
522*de1e4e89SAndroid Build Coastguard Worker rta_getattr_u8(tb[IFLA_BR_VLAN_STATS_ENABLED]));
523*de1e4e89SAndroid Build Coastguard Worker
524*de1e4e89SAndroid Build Coastguard Worker if (tb[IFLA_BR_GROUP_FWD_MASK])
525*de1e4e89SAndroid Build Coastguard Worker print_0xhex(PRINT_ANY,
526*de1e4e89SAndroid Build Coastguard Worker "group_fwd_mask",
527*de1e4e89SAndroid Build Coastguard Worker "group_fwd_mask %#x ",
528*de1e4e89SAndroid Build Coastguard Worker rta_getattr_u16(tb[IFLA_BR_GROUP_FWD_MASK]));
529*de1e4e89SAndroid Build Coastguard Worker
530*de1e4e89SAndroid Build Coastguard Worker if (tb[IFLA_BR_GROUP_ADDR]) {
531*de1e4e89SAndroid Build Coastguard Worker SPRINT_BUF(mac);
532*de1e4e89SAndroid Build Coastguard Worker
533*de1e4e89SAndroid Build Coastguard Worker print_string(PRINT_ANY,
534*de1e4e89SAndroid Build Coastguard Worker "group_addr",
535*de1e4e89SAndroid Build Coastguard Worker "group_address %s ",
536*de1e4e89SAndroid Build Coastguard Worker ll_addr_n2a(RTA_DATA(tb[IFLA_BR_GROUP_ADDR]),
537*de1e4e89SAndroid Build Coastguard Worker RTA_PAYLOAD(tb[IFLA_BR_GROUP_ADDR]),
538*de1e4e89SAndroid Build Coastguard Worker 1 /*ARPHDR_ETHER*/, mac, sizeof(mac)));
539*de1e4e89SAndroid Build Coastguard Worker }
540*de1e4e89SAndroid Build Coastguard Worker
541*de1e4e89SAndroid Build Coastguard Worker if (tb[IFLA_BR_MCAST_SNOOPING])
542*de1e4e89SAndroid Build Coastguard Worker print_uint(PRINT_ANY,
543*de1e4e89SAndroid Build Coastguard Worker "mcast_snooping",
544*de1e4e89SAndroid Build Coastguard Worker "mcast_snooping %u ",
545*de1e4e89SAndroid Build Coastguard Worker rta_getattr_u8(tb[IFLA_BR_MCAST_SNOOPING]));
546*de1e4e89SAndroid Build Coastguard Worker
547*de1e4e89SAndroid Build Coastguard Worker if (tb[IFLA_BR_MCAST_ROUTER])
548*de1e4e89SAndroid Build Coastguard Worker print_uint(PRINT_ANY,
549*de1e4e89SAndroid Build Coastguard Worker "mcast_router",
550*de1e4e89SAndroid Build Coastguard Worker "mcast_router %u ",
551*de1e4e89SAndroid Build Coastguard Worker rta_getattr_u8(tb[IFLA_BR_MCAST_ROUTER]));
552*de1e4e89SAndroid Build Coastguard Worker
553*de1e4e89SAndroid Build Coastguard Worker if (tb[IFLA_BR_MCAST_QUERY_USE_IFADDR])
554*de1e4e89SAndroid Build Coastguard Worker print_uint(PRINT_ANY,
555*de1e4e89SAndroid Build Coastguard Worker "mcast_query_use_ifaddr",
556*de1e4e89SAndroid Build Coastguard Worker "mcast_query_use_ifaddr %u ",
557*de1e4e89SAndroid Build Coastguard Worker rta_getattr_u8(tb[IFLA_BR_MCAST_QUERY_USE_IFADDR]));
558*de1e4e89SAndroid Build Coastguard Worker
559*de1e4e89SAndroid Build Coastguard Worker if (tb[IFLA_BR_MCAST_QUERIER])
560*de1e4e89SAndroid Build Coastguard Worker print_uint(PRINT_ANY,
561*de1e4e89SAndroid Build Coastguard Worker "mcast_querier",
562*de1e4e89SAndroid Build Coastguard Worker "mcast_querier %u ",
563*de1e4e89SAndroid Build Coastguard Worker rta_getattr_u8(tb[IFLA_BR_MCAST_QUERIER]));
564*de1e4e89SAndroid Build Coastguard Worker
565*de1e4e89SAndroid Build Coastguard Worker if (tb[IFLA_BR_MCAST_HASH_ELASTICITY])
566*de1e4e89SAndroid Build Coastguard Worker print_uint(PRINT_ANY,
567*de1e4e89SAndroid Build Coastguard Worker "mcast_hash_elasticity",
568*de1e4e89SAndroid Build Coastguard Worker "mcast_hash_elasticity %u ",
569*de1e4e89SAndroid Build Coastguard Worker rta_getattr_u32(tb[IFLA_BR_MCAST_HASH_ELASTICITY]));
570*de1e4e89SAndroid Build Coastguard Worker
571*de1e4e89SAndroid Build Coastguard Worker if (tb[IFLA_BR_MCAST_HASH_MAX])
572*de1e4e89SAndroid Build Coastguard Worker print_uint(PRINT_ANY,
573*de1e4e89SAndroid Build Coastguard Worker "mcast_hash_max",
574*de1e4e89SAndroid Build Coastguard Worker "mcast_hash_max %u ",
575*de1e4e89SAndroid Build Coastguard Worker rta_getattr_u32(tb[IFLA_BR_MCAST_HASH_MAX]));
576*de1e4e89SAndroid Build Coastguard Worker
577*de1e4e89SAndroid Build Coastguard Worker if (tb[IFLA_BR_MCAST_LAST_MEMBER_CNT])
578*de1e4e89SAndroid Build Coastguard Worker print_uint(PRINT_ANY,
579*de1e4e89SAndroid Build Coastguard Worker "mcast_last_member_cnt",
580*de1e4e89SAndroid Build Coastguard Worker "mcast_last_member_count %u ",
581*de1e4e89SAndroid Build Coastguard Worker rta_getattr_u32(tb[IFLA_BR_MCAST_LAST_MEMBER_CNT]));
582*de1e4e89SAndroid Build Coastguard Worker
583*de1e4e89SAndroid Build Coastguard Worker if (tb[IFLA_BR_MCAST_STARTUP_QUERY_CNT])
584*de1e4e89SAndroid Build Coastguard Worker print_uint(PRINT_ANY,
585*de1e4e89SAndroid Build Coastguard Worker "mcast_startup_query_cnt",
586*de1e4e89SAndroid Build Coastguard Worker "mcast_startup_query_count %u ",
587*de1e4e89SAndroid Build Coastguard Worker rta_getattr_u32(tb[IFLA_BR_MCAST_STARTUP_QUERY_CNT]));
588*de1e4e89SAndroid Build Coastguard Worker
589*de1e4e89SAndroid Build Coastguard Worker if (tb[IFLA_BR_MCAST_LAST_MEMBER_INTVL])
590*de1e4e89SAndroid Build Coastguard Worker print_lluint(PRINT_ANY,
591*de1e4e89SAndroid Build Coastguard Worker "mcast_last_member_intvl",
592*de1e4e89SAndroid Build Coastguard Worker "mcast_last_member_interval %llu ",
593*de1e4e89SAndroid Build Coastguard Worker rta_getattr_u64(tb[IFLA_BR_MCAST_LAST_MEMBER_INTVL]));
594*de1e4e89SAndroid Build Coastguard Worker
595*de1e4e89SAndroid Build Coastguard Worker if (tb[IFLA_BR_MCAST_MEMBERSHIP_INTVL])
596*de1e4e89SAndroid Build Coastguard Worker print_lluint(PRINT_ANY,
597*de1e4e89SAndroid Build Coastguard Worker "mcast_membership_intvl",
598*de1e4e89SAndroid Build Coastguard Worker "mcast_membership_interval %llu ",
599*de1e4e89SAndroid Build Coastguard Worker rta_getattr_u64(tb[IFLA_BR_MCAST_MEMBERSHIP_INTVL]));
600*de1e4e89SAndroid Build Coastguard Worker
601*de1e4e89SAndroid Build Coastguard Worker if (tb[IFLA_BR_MCAST_QUERIER_INTVL])
602*de1e4e89SAndroid Build Coastguard Worker print_lluint(PRINT_ANY,
603*de1e4e89SAndroid Build Coastguard Worker "mcast_querier_intvl",
604*de1e4e89SAndroid Build Coastguard Worker "mcast_querier_interval %llu ",
605*de1e4e89SAndroid Build Coastguard Worker rta_getattr_u64(tb[IFLA_BR_MCAST_QUERIER_INTVL]));
606*de1e4e89SAndroid Build Coastguard Worker
607*de1e4e89SAndroid Build Coastguard Worker if (tb[IFLA_BR_MCAST_QUERY_INTVL])
608*de1e4e89SAndroid Build Coastguard Worker print_lluint(PRINT_ANY,
609*de1e4e89SAndroid Build Coastguard Worker "mcast_query_intvl",
610*de1e4e89SAndroid Build Coastguard Worker "mcast_query_interval %llu ",
611*de1e4e89SAndroid Build Coastguard Worker rta_getattr_u64(tb[IFLA_BR_MCAST_QUERY_INTVL]));
612*de1e4e89SAndroid Build Coastguard Worker
613*de1e4e89SAndroid Build Coastguard Worker if (tb[IFLA_BR_MCAST_QUERY_RESPONSE_INTVL])
614*de1e4e89SAndroid Build Coastguard Worker print_lluint(PRINT_ANY,
615*de1e4e89SAndroid Build Coastguard Worker "mcast_query_response_intvl",
616*de1e4e89SAndroid Build Coastguard Worker "mcast_query_response_interval %llu ",
617*de1e4e89SAndroid Build Coastguard Worker rta_getattr_u64(tb[IFLA_BR_MCAST_QUERY_RESPONSE_INTVL]));
618*de1e4e89SAndroid Build Coastguard Worker
619*de1e4e89SAndroid Build Coastguard Worker if (tb[IFLA_BR_MCAST_STARTUP_QUERY_INTVL])
620*de1e4e89SAndroid Build Coastguard Worker print_lluint(PRINT_ANY,
621*de1e4e89SAndroid Build Coastguard Worker "mcast_startup_query_intvl",
622*de1e4e89SAndroid Build Coastguard Worker "mcast_startup_query_interval %llu ",
623*de1e4e89SAndroid Build Coastguard Worker rta_getattr_u64(tb[IFLA_BR_MCAST_STARTUP_QUERY_INTVL]));
624*de1e4e89SAndroid Build Coastguard Worker
625*de1e4e89SAndroid Build Coastguard Worker if (tb[IFLA_BR_MCAST_STATS_ENABLED])
626*de1e4e89SAndroid Build Coastguard Worker print_uint(PRINT_ANY,
627*de1e4e89SAndroid Build Coastguard Worker "mcast_stats_enabled",
628*de1e4e89SAndroid Build Coastguard Worker "mcast_stats_enabled %u ",
629*de1e4e89SAndroid Build Coastguard Worker rta_getattr_u8(tb[IFLA_BR_MCAST_STATS_ENABLED]));
630*de1e4e89SAndroid Build Coastguard Worker
631*de1e4e89SAndroid Build Coastguard Worker if (tb[IFLA_BR_MCAST_IGMP_VERSION])
632*de1e4e89SAndroid Build Coastguard Worker print_uint(PRINT_ANY,
633*de1e4e89SAndroid Build Coastguard Worker "mcast_igmp_version",
634*de1e4e89SAndroid Build Coastguard Worker "mcast_igmp_version %u ",
635*de1e4e89SAndroid Build Coastguard Worker rta_getattr_u8(tb[IFLA_BR_MCAST_IGMP_VERSION]));
636*de1e4e89SAndroid Build Coastguard Worker
637*de1e4e89SAndroid Build Coastguard Worker if (tb[IFLA_BR_MCAST_MLD_VERSION])
638*de1e4e89SAndroid Build Coastguard Worker print_uint(PRINT_ANY,
639*de1e4e89SAndroid Build Coastguard Worker "mcast_mld_version",
640*de1e4e89SAndroid Build Coastguard Worker "mcast_mld_version %u ",
641*de1e4e89SAndroid Build Coastguard Worker rta_getattr_u8(tb[IFLA_BR_MCAST_MLD_VERSION]));
642*de1e4e89SAndroid Build Coastguard Worker
643*de1e4e89SAndroid Build Coastguard Worker if (tb[IFLA_BR_NF_CALL_IPTABLES])
644*de1e4e89SAndroid Build Coastguard Worker print_uint(PRINT_ANY,
645*de1e4e89SAndroid Build Coastguard Worker "nf_call_iptables",
646*de1e4e89SAndroid Build Coastguard Worker "nf_call_iptables %u ",
647*de1e4e89SAndroid Build Coastguard Worker rta_getattr_u8(tb[IFLA_BR_NF_CALL_IPTABLES]));
648*de1e4e89SAndroid Build Coastguard Worker
649*de1e4e89SAndroid Build Coastguard Worker if (tb[IFLA_BR_NF_CALL_IP6TABLES])
650*de1e4e89SAndroid Build Coastguard Worker print_uint(PRINT_ANY,
651*de1e4e89SAndroid Build Coastguard Worker "nf_call_ip6tables",
652*de1e4e89SAndroid Build Coastguard Worker "nf_call_ip6tables %u ",
653*de1e4e89SAndroid Build Coastguard Worker rta_getattr_u8(tb[IFLA_BR_NF_CALL_IP6TABLES]));
654*de1e4e89SAndroid Build Coastguard Worker
655*de1e4e89SAndroid Build Coastguard Worker if (tb[IFLA_BR_NF_CALL_ARPTABLES])
656*de1e4e89SAndroid Build Coastguard Worker print_uint(PRINT_ANY,
657*de1e4e89SAndroid Build Coastguard Worker "nf_call_arptables",
658*de1e4e89SAndroid Build Coastguard Worker "nf_call_arptables %u ",
659*de1e4e89SAndroid Build Coastguard Worker rta_getattr_u8(tb[IFLA_BR_NF_CALL_ARPTABLES]));
660*de1e4e89SAndroid Build Coastguard Worker }
661*de1e4e89SAndroid Build Coastguard Worker
bridge_print_help(struct link_util * lu,int argc,char ** argv,FILE * f)662*de1e4e89SAndroid Build Coastguard Worker static void bridge_print_help(struct link_util *lu, int argc, char **argv,
663*de1e4e89SAndroid Build Coastguard Worker FILE *f)
664*de1e4e89SAndroid Build Coastguard Worker {
665*de1e4e89SAndroid Build Coastguard Worker print_explain(f);
666*de1e4e89SAndroid Build Coastguard Worker }
667*de1e4e89SAndroid Build Coastguard Worker
bridge_print_xstats_help(struct link_util * lu,FILE * f)668*de1e4e89SAndroid Build Coastguard Worker static void bridge_print_xstats_help(struct link_util *lu, FILE *f)
669*de1e4e89SAndroid Build Coastguard Worker {
670*de1e4e89SAndroid Build Coastguard Worker fprintf(f, "Usage: ... %s [ igmp ] [ dev DEVICE ]\n", lu->id);
671*de1e4e89SAndroid Build Coastguard Worker }
672*de1e4e89SAndroid Build Coastguard Worker
bridge_print_stats_attr(FILE * f,struct rtattr * attr,int ifindex)673*de1e4e89SAndroid Build Coastguard Worker static void bridge_print_stats_attr(FILE *f, struct rtattr *attr, int ifindex)
674*de1e4e89SAndroid Build Coastguard Worker {
675*de1e4e89SAndroid Build Coastguard Worker struct rtattr *brtb[LINK_XSTATS_TYPE_MAX+1];
676*de1e4e89SAndroid Build Coastguard Worker struct br_mcast_stats *mstats;
677*de1e4e89SAndroid Build Coastguard Worker struct rtattr *i, *list;
678*de1e4e89SAndroid Build Coastguard Worker const char *ifname = "";
679*de1e4e89SAndroid Build Coastguard Worker int rem;
680*de1e4e89SAndroid Build Coastguard Worker
681*de1e4e89SAndroid Build Coastguard Worker parse_rtattr(brtb, LINK_XSTATS_TYPE_MAX, RTA_DATA(attr),
682*de1e4e89SAndroid Build Coastguard Worker RTA_PAYLOAD(attr));
683*de1e4e89SAndroid Build Coastguard Worker if (!brtb[LINK_XSTATS_TYPE_BRIDGE])
684*de1e4e89SAndroid Build Coastguard Worker return;
685*de1e4e89SAndroid Build Coastguard Worker
686*de1e4e89SAndroid Build Coastguard Worker list = brtb[LINK_XSTATS_TYPE_BRIDGE];
687*de1e4e89SAndroid Build Coastguard Worker rem = RTA_PAYLOAD(list);
688*de1e4e89SAndroid Build Coastguard Worker for (i = RTA_DATA(list); RTA_OK(i, rem); i = RTA_NEXT(i, rem)) {
689*de1e4e89SAndroid Build Coastguard Worker if (xstats_print_attr && i->rta_type != xstats_print_attr)
690*de1e4e89SAndroid Build Coastguard Worker continue;
691*de1e4e89SAndroid Build Coastguard Worker switch (i->rta_type) {
692*de1e4e89SAndroid Build Coastguard Worker case BRIDGE_XSTATS_MCAST:
693*de1e4e89SAndroid Build Coastguard Worker mstats = RTA_DATA(i);
694*de1e4e89SAndroid Build Coastguard Worker ifname = ll_index_to_name(ifindex);
695*de1e4e89SAndroid Build Coastguard Worker fprintf(f, "%-16s\n", ifname);
696*de1e4e89SAndroid Build Coastguard Worker fprintf(f, "%-16s IGMP queries:\n", "");
697*de1e4e89SAndroid Build Coastguard Worker fprintf(f, "%-16s RX: v1 %llu v2 %llu v3 %llu\n",
698*de1e4e89SAndroid Build Coastguard Worker "",
699*de1e4e89SAndroid Build Coastguard Worker mstats->igmp_v1queries[BR_MCAST_DIR_RX],
700*de1e4e89SAndroid Build Coastguard Worker mstats->igmp_v2queries[BR_MCAST_DIR_RX],
701*de1e4e89SAndroid Build Coastguard Worker mstats->igmp_v3queries[BR_MCAST_DIR_RX]);
702*de1e4e89SAndroid Build Coastguard Worker fprintf(f, "%-16s TX: v1 %llu v2 %llu v3 %llu\n",
703*de1e4e89SAndroid Build Coastguard Worker "",
704*de1e4e89SAndroid Build Coastguard Worker mstats->igmp_v1queries[BR_MCAST_DIR_TX],
705*de1e4e89SAndroid Build Coastguard Worker mstats->igmp_v2queries[BR_MCAST_DIR_TX],
706*de1e4e89SAndroid Build Coastguard Worker mstats->igmp_v3queries[BR_MCAST_DIR_TX]);
707*de1e4e89SAndroid Build Coastguard Worker
708*de1e4e89SAndroid Build Coastguard Worker fprintf(f, "%-16s IGMP reports:\n", "");
709*de1e4e89SAndroid Build Coastguard Worker fprintf(f, "%-16s RX: v1 %llu v2 %llu v3 %llu\n",
710*de1e4e89SAndroid Build Coastguard Worker "",
711*de1e4e89SAndroid Build Coastguard Worker mstats->igmp_v1reports[BR_MCAST_DIR_RX],
712*de1e4e89SAndroid Build Coastguard Worker mstats->igmp_v2reports[BR_MCAST_DIR_RX],
713*de1e4e89SAndroid Build Coastguard Worker mstats->igmp_v3reports[BR_MCAST_DIR_RX]);
714*de1e4e89SAndroid Build Coastguard Worker fprintf(f, "%-16s TX: v1 %llu v2 %llu v3 %llu\n",
715*de1e4e89SAndroid Build Coastguard Worker "",
716*de1e4e89SAndroid Build Coastguard Worker mstats->igmp_v1reports[BR_MCAST_DIR_TX],
717*de1e4e89SAndroid Build Coastguard Worker mstats->igmp_v2reports[BR_MCAST_DIR_TX],
718*de1e4e89SAndroid Build Coastguard Worker mstats->igmp_v3reports[BR_MCAST_DIR_TX]);
719*de1e4e89SAndroid Build Coastguard Worker
720*de1e4e89SAndroid Build Coastguard Worker fprintf(f, "%-16s IGMP leaves: RX: %llu TX: %llu\n",
721*de1e4e89SAndroid Build Coastguard Worker "",
722*de1e4e89SAndroid Build Coastguard Worker mstats->igmp_leaves[BR_MCAST_DIR_RX],
723*de1e4e89SAndroid Build Coastguard Worker mstats->igmp_leaves[BR_MCAST_DIR_TX]);
724*de1e4e89SAndroid Build Coastguard Worker
725*de1e4e89SAndroid Build Coastguard Worker fprintf(f, "%-16s IGMP parse errors: %llu\n",
726*de1e4e89SAndroid Build Coastguard Worker "", mstats->igmp_parse_errors);
727*de1e4e89SAndroid Build Coastguard Worker
728*de1e4e89SAndroid Build Coastguard Worker fprintf(f, "%-16s MLD queries:\n", "");
729*de1e4e89SAndroid Build Coastguard Worker fprintf(f, "%-16s RX: v1 %llu v2 %llu\n",
730*de1e4e89SAndroid Build Coastguard Worker "",
731*de1e4e89SAndroid Build Coastguard Worker mstats->mld_v1queries[BR_MCAST_DIR_RX],
732*de1e4e89SAndroid Build Coastguard Worker mstats->mld_v2queries[BR_MCAST_DIR_RX]);
733*de1e4e89SAndroid Build Coastguard Worker fprintf(f, "%-16s TX: v1 %llu v2 %llu\n",
734*de1e4e89SAndroid Build Coastguard Worker "",
735*de1e4e89SAndroid Build Coastguard Worker mstats->mld_v1queries[BR_MCAST_DIR_TX],
736*de1e4e89SAndroid Build Coastguard Worker mstats->mld_v2queries[BR_MCAST_DIR_TX]);
737*de1e4e89SAndroid Build Coastguard Worker
738*de1e4e89SAndroid Build Coastguard Worker fprintf(f, "%-16s MLD reports:\n", "");
739*de1e4e89SAndroid Build Coastguard Worker fprintf(f, "%-16s RX: v1 %llu v2 %llu\n",
740*de1e4e89SAndroid Build Coastguard Worker "",
741*de1e4e89SAndroid Build Coastguard Worker mstats->mld_v1reports[BR_MCAST_DIR_RX],
742*de1e4e89SAndroid Build Coastguard Worker mstats->mld_v2reports[BR_MCAST_DIR_RX]);
743*de1e4e89SAndroid Build Coastguard Worker fprintf(f, "%-16s TX: v1 %llu v2 %llu\n",
744*de1e4e89SAndroid Build Coastguard Worker "",
745*de1e4e89SAndroid Build Coastguard Worker mstats->mld_v1reports[BR_MCAST_DIR_TX],
746*de1e4e89SAndroid Build Coastguard Worker mstats->mld_v2reports[BR_MCAST_DIR_TX]);
747*de1e4e89SAndroid Build Coastguard Worker
748*de1e4e89SAndroid Build Coastguard Worker fprintf(f, "%-16s MLD leaves: RX: %llu TX: %llu\n",
749*de1e4e89SAndroid Build Coastguard Worker "",
750*de1e4e89SAndroid Build Coastguard Worker mstats->mld_leaves[BR_MCAST_DIR_RX],
751*de1e4e89SAndroid Build Coastguard Worker mstats->mld_leaves[BR_MCAST_DIR_TX]);
752*de1e4e89SAndroid Build Coastguard Worker
753*de1e4e89SAndroid Build Coastguard Worker fprintf(f, "%-16s MLD parse errors: %llu\n",
754*de1e4e89SAndroid Build Coastguard Worker "", mstats->mld_parse_errors);
755*de1e4e89SAndroid Build Coastguard Worker break;
756*de1e4e89SAndroid Build Coastguard Worker }
757*de1e4e89SAndroid Build Coastguard Worker }
758*de1e4e89SAndroid Build Coastguard Worker }
759*de1e4e89SAndroid Build Coastguard Worker
bridge_print_xstats(const struct sockaddr_nl * who,struct nlmsghdr * n,void * arg)760*de1e4e89SAndroid Build Coastguard Worker int bridge_print_xstats(const struct sockaddr_nl *who,
761*de1e4e89SAndroid Build Coastguard Worker struct nlmsghdr *n, void *arg)
762*de1e4e89SAndroid Build Coastguard Worker {
763*de1e4e89SAndroid Build Coastguard Worker struct if_stats_msg *ifsm = NLMSG_DATA(n);
764*de1e4e89SAndroid Build Coastguard Worker struct rtattr *tb[IFLA_STATS_MAX+1];
765*de1e4e89SAndroid Build Coastguard Worker int len = n->nlmsg_len;
766*de1e4e89SAndroid Build Coastguard Worker FILE *fp = arg;
767*de1e4e89SAndroid Build Coastguard Worker
768*de1e4e89SAndroid Build Coastguard Worker len -= NLMSG_LENGTH(sizeof(*ifsm));
769*de1e4e89SAndroid Build Coastguard Worker if (len < 0) {
770*de1e4e89SAndroid Build Coastguard Worker fprintf(stderr, "BUG: wrong nlmsg len %d\n", len);
771*de1e4e89SAndroid Build Coastguard Worker return -1;
772*de1e4e89SAndroid Build Coastguard Worker }
773*de1e4e89SAndroid Build Coastguard Worker if (filter_index && filter_index != ifsm->ifindex)
774*de1e4e89SAndroid Build Coastguard Worker return 0;
775*de1e4e89SAndroid Build Coastguard Worker
776*de1e4e89SAndroid Build Coastguard Worker parse_rtattr(tb, IFLA_STATS_MAX, IFLA_STATS_RTA(ifsm), len);
777*de1e4e89SAndroid Build Coastguard Worker if (tb[IFLA_STATS_LINK_XSTATS])
778*de1e4e89SAndroid Build Coastguard Worker bridge_print_stats_attr(fp, tb[IFLA_STATS_LINK_XSTATS],
779*de1e4e89SAndroid Build Coastguard Worker ifsm->ifindex);
780*de1e4e89SAndroid Build Coastguard Worker
781*de1e4e89SAndroid Build Coastguard Worker if (tb[IFLA_STATS_LINK_XSTATS_SLAVE])
782*de1e4e89SAndroid Build Coastguard Worker bridge_print_stats_attr(fp, tb[IFLA_STATS_LINK_XSTATS_SLAVE],
783*de1e4e89SAndroid Build Coastguard Worker ifsm->ifindex);
784*de1e4e89SAndroid Build Coastguard Worker
785*de1e4e89SAndroid Build Coastguard Worker return 0;
786*de1e4e89SAndroid Build Coastguard Worker }
787*de1e4e89SAndroid Build Coastguard Worker
bridge_parse_xstats(struct link_util * lu,int argc,char ** argv)788*de1e4e89SAndroid Build Coastguard Worker int bridge_parse_xstats(struct link_util *lu, int argc, char **argv)
789*de1e4e89SAndroid Build Coastguard Worker {
790*de1e4e89SAndroid Build Coastguard Worker while (argc > 0) {
791*de1e4e89SAndroid Build Coastguard Worker if (strcmp(*argv, "igmp") == 0 || strcmp(*argv, "mcast") == 0) {
792*de1e4e89SAndroid Build Coastguard Worker xstats_print_attr = BRIDGE_XSTATS_MCAST;
793*de1e4e89SAndroid Build Coastguard Worker } else if (strcmp(*argv, "dev") == 0) {
794*de1e4e89SAndroid Build Coastguard Worker NEXT_ARG();
795*de1e4e89SAndroid Build Coastguard Worker filter_index = if_nametoindex(*argv);
796*de1e4e89SAndroid Build Coastguard Worker if (filter_index == 0) {
797*de1e4e89SAndroid Build Coastguard Worker fprintf(stderr, "Cannot find device \"%s\"\n",
798*de1e4e89SAndroid Build Coastguard Worker *argv);
799*de1e4e89SAndroid Build Coastguard Worker return -1;
800*de1e4e89SAndroid Build Coastguard Worker }
801*de1e4e89SAndroid Build Coastguard Worker } else if (strcmp(*argv, "help") == 0) {
802*de1e4e89SAndroid Build Coastguard Worker bridge_print_xstats_help(lu, stdout);
803*de1e4e89SAndroid Build Coastguard Worker exit(0);
804*de1e4e89SAndroid Build Coastguard Worker } else {
805*de1e4e89SAndroid Build Coastguard Worker invarg("unknown attribute", *argv);
806*de1e4e89SAndroid Build Coastguard Worker }
807*de1e4e89SAndroid Build Coastguard Worker argc--; argv++;
808*de1e4e89SAndroid Build Coastguard Worker }
809*de1e4e89SAndroid Build Coastguard Worker
810*de1e4e89SAndroid Build Coastguard Worker return 0;
811*de1e4e89SAndroid Build Coastguard Worker }
812*de1e4e89SAndroid Build Coastguard Worker
813*de1e4e89SAndroid Build Coastguard Worker struct link_util bridge_link_util = {
814*de1e4e89SAndroid Build Coastguard Worker .id = "bridge",
815*de1e4e89SAndroid Build Coastguard Worker .maxattr = IFLA_BR_MAX,
816*de1e4e89SAndroid Build Coastguard Worker .parse_opt = bridge_parse_opt,
817*de1e4e89SAndroid Build Coastguard Worker .print_opt = bridge_print_opt,
818*de1e4e89SAndroid Build Coastguard Worker .print_help = bridge_print_help,
819*de1e4e89SAndroid Build Coastguard Worker .parse_ifla_xstats = bridge_parse_xstats,
820*de1e4e89SAndroid Build Coastguard Worker .print_ifla_xstats = bridge_print_xstats,
821*de1e4e89SAndroid Build Coastguard Worker };
822