xref: /aosp_15_r20/external/iproute2/ip/iplink_bridge_slave.c (revision de1e4e894b0c224df933550f0afdecc354b238c4)
1*de1e4e89SAndroid Build Coastguard Worker /*
2*de1e4e89SAndroid Build Coastguard Worker  * iplink_bridge_slave.c	Bridge slave 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 <sys/socket.h>
14*de1e4e89SAndroid Build Coastguard Worker #include <netinet/in.h>
15*de1e4e89SAndroid Build Coastguard Worker #include <linux/if_link.h>
16*de1e4e89SAndroid Build Coastguard Worker #include <linux/if_bridge.h>
17*de1e4e89SAndroid Build Coastguard Worker 
18*de1e4e89SAndroid Build Coastguard Worker #include "rt_names.h"
19*de1e4e89SAndroid Build Coastguard Worker #include "utils.h"
20*de1e4e89SAndroid Build Coastguard Worker #include "ip_common.h"
21*de1e4e89SAndroid Build Coastguard Worker 
print_explain(FILE * f)22*de1e4e89SAndroid Build Coastguard Worker static void print_explain(FILE *f)
23*de1e4e89SAndroid Build Coastguard Worker {
24*de1e4e89SAndroid Build Coastguard Worker 	fprintf(f,
25*de1e4e89SAndroid Build Coastguard Worker 		"Usage: ... bridge_slave [ fdb_flush ]\n"
26*de1e4e89SAndroid Build Coastguard Worker 		"                        [ state STATE ]\n"
27*de1e4e89SAndroid Build Coastguard Worker 		"                        [ priority PRIO ]\n"
28*de1e4e89SAndroid Build Coastguard Worker 		"                        [ cost COST ]\n"
29*de1e4e89SAndroid Build Coastguard Worker 		"                        [ guard {on | off} ]\n"
30*de1e4e89SAndroid Build Coastguard Worker 		"                        [ hairpin {on | off} ]\n"
31*de1e4e89SAndroid Build Coastguard Worker 		"                        [ fastleave {on | off} ]\n"
32*de1e4e89SAndroid Build Coastguard Worker 		"                        [ root_block {on | off} ]\n"
33*de1e4e89SAndroid Build Coastguard Worker 		"                        [ learning {on | off} ]\n"
34*de1e4e89SAndroid Build Coastguard Worker 		"                        [ flood {on | off} ]\n"
35*de1e4e89SAndroid Build Coastguard Worker 		"                        [ proxy_arp {on | off} ]\n"
36*de1e4e89SAndroid Build Coastguard Worker 		"                        [ proxy_arp_wifi {on | off} ]\n"
37*de1e4e89SAndroid Build Coastguard Worker 		"                        [ mcast_router MULTICAST_ROUTER ]\n"
38*de1e4e89SAndroid Build Coastguard Worker 		"                        [ mcast_fast_leave {on | off} ]\n"
39*de1e4e89SAndroid Build Coastguard Worker 		"                        [ mcast_flood {on | off} ]\n"
40*de1e4e89SAndroid Build Coastguard Worker 	);
41*de1e4e89SAndroid Build Coastguard Worker }
42*de1e4e89SAndroid Build Coastguard Worker 
explain(void)43*de1e4e89SAndroid Build Coastguard Worker static void explain(void)
44*de1e4e89SAndroid Build Coastguard Worker {
45*de1e4e89SAndroid Build Coastguard Worker 	print_explain(stderr);
46*de1e4e89SAndroid Build Coastguard Worker }
47*de1e4e89SAndroid Build Coastguard Worker 
48*de1e4e89SAndroid Build Coastguard Worker static const char *port_states[] = {
49*de1e4e89SAndroid Build Coastguard Worker 	[BR_STATE_DISABLED] = "disabled",
50*de1e4e89SAndroid Build Coastguard Worker 	[BR_STATE_LISTENING] = "listening",
51*de1e4e89SAndroid Build Coastguard Worker 	[BR_STATE_LEARNING] = "learning",
52*de1e4e89SAndroid Build Coastguard Worker 	[BR_STATE_FORWARDING] = "forwarding",
53*de1e4e89SAndroid Build Coastguard Worker 	[BR_STATE_BLOCKING] = "blocking",
54*de1e4e89SAndroid Build Coastguard Worker };
55*de1e4e89SAndroid Build Coastguard Worker 
print_portstate(FILE * f,__u8 state)56*de1e4e89SAndroid Build Coastguard Worker static void print_portstate(FILE *f, __u8 state)
57*de1e4e89SAndroid Build Coastguard Worker {
58*de1e4e89SAndroid Build Coastguard Worker 	if (state <= BR_STATE_BLOCKING)
59*de1e4e89SAndroid Build Coastguard Worker 		print_string(PRINT_ANY,
60*de1e4e89SAndroid Build Coastguard Worker 			     "state",
61*de1e4e89SAndroid Build Coastguard Worker 			     "state %s ",
62*de1e4e89SAndroid Build Coastguard Worker 			     port_states[state]);
63*de1e4e89SAndroid Build Coastguard Worker 	else
64*de1e4e89SAndroid Build Coastguard Worker 		print_int(PRINT_ANY, "state_index", "state (%d) ", state);
65*de1e4e89SAndroid Build Coastguard Worker }
66*de1e4e89SAndroid Build Coastguard Worker 
_print_onoff(FILE * f,char * json_flag,char * flag,__u8 val)67*de1e4e89SAndroid Build Coastguard Worker static void _print_onoff(FILE *f, char *json_flag, char *flag, __u8 val)
68*de1e4e89SAndroid Build Coastguard Worker {
69*de1e4e89SAndroid Build Coastguard Worker 	if (is_json_context())
70*de1e4e89SAndroid Build Coastguard Worker 		print_bool(PRINT_JSON, flag, NULL, val);
71*de1e4e89SAndroid Build Coastguard Worker 	else
72*de1e4e89SAndroid Build Coastguard Worker 		fprintf(f, "%s %s ", flag, val ? "on" : "off");
73*de1e4e89SAndroid Build Coastguard Worker }
74*de1e4e89SAndroid Build Coastguard Worker 
_print_hex(FILE * f,const char * json_attr,const char * attr,__u16 val)75*de1e4e89SAndroid Build Coastguard Worker static void _print_hex(FILE *f,
76*de1e4e89SAndroid Build Coastguard Worker 		       const char *json_attr,
77*de1e4e89SAndroid Build Coastguard Worker 		       const char *attr,
78*de1e4e89SAndroid Build Coastguard Worker 		       __u16 val)
79*de1e4e89SAndroid Build Coastguard Worker {
80*de1e4e89SAndroid Build Coastguard Worker 	if (is_json_context()) {
81*de1e4e89SAndroid Build Coastguard Worker 		SPRINT_BUF(b1);
82*de1e4e89SAndroid Build Coastguard Worker 
83*de1e4e89SAndroid Build Coastguard Worker 		snprintf(b1, sizeof(b1), "0x%x", val);
84*de1e4e89SAndroid Build Coastguard Worker 		print_string(PRINT_JSON, json_attr, NULL, b1);
85*de1e4e89SAndroid Build Coastguard Worker 	} else {
86*de1e4e89SAndroid Build Coastguard Worker 		fprintf(f, "%s 0x%x ", attr, val);
87*de1e4e89SAndroid Build Coastguard Worker 	}
88*de1e4e89SAndroid Build Coastguard Worker }
89*de1e4e89SAndroid Build Coastguard Worker 
_print_timer(FILE * f,const char * attr,struct rtattr * timer)90*de1e4e89SAndroid Build Coastguard Worker static void _print_timer(FILE *f, const char *attr, struct rtattr *timer)
91*de1e4e89SAndroid Build Coastguard Worker {
92*de1e4e89SAndroid Build Coastguard Worker 	struct timeval tv;
93*de1e4e89SAndroid Build Coastguard Worker 
94*de1e4e89SAndroid Build Coastguard Worker 	__jiffies_to_tv(&tv, rta_getattr_u64(timer));
95*de1e4e89SAndroid Build Coastguard Worker 	if (is_json_context()) {
96*de1e4e89SAndroid Build Coastguard Worker 		json_writer_t *jw = get_json_writer();
97*de1e4e89SAndroid Build Coastguard Worker 
98*de1e4e89SAndroid Build Coastguard Worker 		jsonw_name(jw, attr);
99*de1e4e89SAndroid Build Coastguard Worker 		jsonw_printf(jw, "%i.%.2i",
100*de1e4e89SAndroid Build Coastguard Worker 			     (int)tv.tv_sec, (int)tv.tv_usec / 10000);
101*de1e4e89SAndroid Build Coastguard Worker 	} else {
102*de1e4e89SAndroid Build Coastguard Worker 		fprintf(f, "%s %4i.%.2i ", attr, (int)tv.tv_sec,
103*de1e4e89SAndroid Build Coastguard Worker 			(int)tv.tv_usec / 10000);
104*de1e4e89SAndroid Build Coastguard Worker 	}
105*de1e4e89SAndroid Build Coastguard Worker }
106*de1e4e89SAndroid Build Coastguard Worker 
bridge_slave_print_opt(struct link_util * lu,FILE * f,struct rtattr * tb[])107*de1e4e89SAndroid Build Coastguard Worker static void bridge_slave_print_opt(struct link_util *lu, FILE *f,
108*de1e4e89SAndroid Build Coastguard Worker 				   struct rtattr *tb[])
109*de1e4e89SAndroid Build Coastguard Worker {
110*de1e4e89SAndroid Build Coastguard Worker 	if (!tb)
111*de1e4e89SAndroid Build Coastguard Worker 		return;
112*de1e4e89SAndroid Build Coastguard Worker 
113*de1e4e89SAndroid Build Coastguard Worker 	if (tb[IFLA_BRPORT_STATE])
114*de1e4e89SAndroid Build Coastguard Worker 		print_portstate(f, rta_getattr_u8(tb[IFLA_BRPORT_STATE]));
115*de1e4e89SAndroid Build Coastguard Worker 
116*de1e4e89SAndroid Build Coastguard Worker 	if (tb[IFLA_BRPORT_PRIORITY])
117*de1e4e89SAndroid Build Coastguard Worker 		print_int(PRINT_ANY,
118*de1e4e89SAndroid Build Coastguard Worker 			  "priority",
119*de1e4e89SAndroid Build Coastguard Worker 			  "priority %d ",
120*de1e4e89SAndroid Build Coastguard Worker 			  rta_getattr_u16(tb[IFLA_BRPORT_PRIORITY]));
121*de1e4e89SAndroid Build Coastguard Worker 
122*de1e4e89SAndroid Build Coastguard Worker 	if (tb[IFLA_BRPORT_COST])
123*de1e4e89SAndroid Build Coastguard Worker 		print_int(PRINT_ANY,
124*de1e4e89SAndroid Build Coastguard Worker 			  "cost",
125*de1e4e89SAndroid Build Coastguard Worker 			  "cost %d ",
126*de1e4e89SAndroid Build Coastguard Worker 			  rta_getattr_u32(tb[IFLA_BRPORT_COST]));
127*de1e4e89SAndroid Build Coastguard Worker 
128*de1e4e89SAndroid Build Coastguard Worker 	if (tb[IFLA_BRPORT_MODE])
129*de1e4e89SAndroid Build Coastguard Worker 		_print_onoff(f, "mode", "hairpin",
130*de1e4e89SAndroid Build Coastguard Worker 			     rta_getattr_u8(tb[IFLA_BRPORT_MODE]));
131*de1e4e89SAndroid Build Coastguard Worker 
132*de1e4e89SAndroid Build Coastguard Worker 	if (tb[IFLA_BRPORT_GUARD])
133*de1e4e89SAndroid Build Coastguard Worker 		_print_onoff(f, "guard", "guard",
134*de1e4e89SAndroid Build Coastguard Worker 			     rta_getattr_u8(tb[IFLA_BRPORT_GUARD]));
135*de1e4e89SAndroid Build Coastguard Worker 
136*de1e4e89SAndroid Build Coastguard Worker 	if (tb[IFLA_BRPORT_PROTECT])
137*de1e4e89SAndroid Build Coastguard Worker 		_print_onoff(f, "protect", "root_block",
138*de1e4e89SAndroid Build Coastguard Worker 			     rta_getattr_u8(tb[IFLA_BRPORT_PROTECT]));
139*de1e4e89SAndroid Build Coastguard Worker 
140*de1e4e89SAndroid Build Coastguard Worker 	if (tb[IFLA_BRPORT_FAST_LEAVE])
141*de1e4e89SAndroid Build Coastguard Worker 		_print_onoff(f, "fast_leave", "fastleave",
142*de1e4e89SAndroid Build Coastguard Worker 			     rta_getattr_u8(tb[IFLA_BRPORT_FAST_LEAVE]));
143*de1e4e89SAndroid Build Coastguard Worker 
144*de1e4e89SAndroid Build Coastguard Worker 	if (tb[IFLA_BRPORT_LEARNING])
145*de1e4e89SAndroid Build Coastguard Worker 		_print_onoff(f, "learning", "learning",
146*de1e4e89SAndroid Build Coastguard Worker 			     rta_getattr_u8(tb[IFLA_BRPORT_LEARNING]));
147*de1e4e89SAndroid Build Coastguard Worker 
148*de1e4e89SAndroid Build Coastguard Worker 	if (tb[IFLA_BRPORT_UNICAST_FLOOD])
149*de1e4e89SAndroid Build Coastguard Worker 		_print_onoff(f, "unicast_flood", "flood",
150*de1e4e89SAndroid Build Coastguard Worker 			     rta_getattr_u8(tb[IFLA_BRPORT_UNICAST_FLOOD]));
151*de1e4e89SAndroid Build Coastguard Worker 
152*de1e4e89SAndroid Build Coastguard Worker 	if (tb[IFLA_BRPORT_ID])
153*de1e4e89SAndroid Build Coastguard Worker 		_print_hex(f, "id", "port_id",
154*de1e4e89SAndroid Build Coastguard Worker 			   rta_getattr_u16(tb[IFLA_BRPORT_ID]));
155*de1e4e89SAndroid Build Coastguard Worker 
156*de1e4e89SAndroid Build Coastguard Worker 	if (tb[IFLA_BRPORT_NO])
157*de1e4e89SAndroid Build Coastguard Worker 		_print_hex(f, "no", "port_no",
158*de1e4e89SAndroid Build Coastguard Worker 			   rta_getattr_u16(tb[IFLA_BRPORT_NO]));
159*de1e4e89SAndroid Build Coastguard Worker 
160*de1e4e89SAndroid Build Coastguard Worker 	if (tb[IFLA_BRPORT_DESIGNATED_PORT])
161*de1e4e89SAndroid Build Coastguard Worker 		print_uint(PRINT_ANY,
162*de1e4e89SAndroid Build Coastguard Worker 			   "designated_port",
163*de1e4e89SAndroid Build Coastguard Worker 			   "designated_port %u ",
164*de1e4e89SAndroid Build Coastguard Worker 			   rta_getattr_u16(tb[IFLA_BRPORT_DESIGNATED_PORT]));
165*de1e4e89SAndroid Build Coastguard Worker 
166*de1e4e89SAndroid Build Coastguard Worker 	if (tb[IFLA_BRPORT_DESIGNATED_COST])
167*de1e4e89SAndroid Build Coastguard Worker 		print_uint(PRINT_ANY,
168*de1e4e89SAndroid Build Coastguard Worker 			   "designated_cost",
169*de1e4e89SAndroid Build Coastguard Worker 			   "designated_cost %u ",
170*de1e4e89SAndroid Build Coastguard Worker 			   rta_getattr_u16(tb[IFLA_BRPORT_DESIGNATED_COST]));
171*de1e4e89SAndroid Build Coastguard Worker 
172*de1e4e89SAndroid Build Coastguard Worker 	if (tb[IFLA_BRPORT_BRIDGE_ID]) {
173*de1e4e89SAndroid Build Coastguard Worker 		char bridge_id[32];
174*de1e4e89SAndroid Build Coastguard Worker 
175*de1e4e89SAndroid Build Coastguard Worker 		br_dump_bridge_id(RTA_DATA(tb[IFLA_BRPORT_BRIDGE_ID]),
176*de1e4e89SAndroid Build Coastguard Worker 				  bridge_id, sizeof(bridge_id));
177*de1e4e89SAndroid Build Coastguard Worker 		print_string(PRINT_ANY,
178*de1e4e89SAndroid Build Coastguard Worker 			     "bridge_id",
179*de1e4e89SAndroid Build Coastguard Worker 			     "designated_bridge %s ",
180*de1e4e89SAndroid Build Coastguard Worker 			     bridge_id);
181*de1e4e89SAndroid Build Coastguard Worker 	}
182*de1e4e89SAndroid Build Coastguard Worker 
183*de1e4e89SAndroid Build Coastguard Worker 	if (tb[IFLA_BRPORT_ROOT_ID]) {
184*de1e4e89SAndroid Build Coastguard Worker 		char root_id[32];
185*de1e4e89SAndroid Build Coastguard Worker 
186*de1e4e89SAndroid Build Coastguard Worker 		br_dump_bridge_id(RTA_DATA(tb[IFLA_BRPORT_ROOT_ID]),
187*de1e4e89SAndroid Build Coastguard Worker 				  root_id, sizeof(root_id));
188*de1e4e89SAndroid Build Coastguard Worker 		print_string(PRINT_ANY,
189*de1e4e89SAndroid Build Coastguard Worker 			     "root_id",
190*de1e4e89SAndroid Build Coastguard Worker 			     "designated_root %s ", root_id);
191*de1e4e89SAndroid Build Coastguard Worker 	}
192*de1e4e89SAndroid Build Coastguard Worker 
193*de1e4e89SAndroid Build Coastguard Worker 	if (tb[IFLA_BRPORT_HOLD_TIMER])
194*de1e4e89SAndroid Build Coastguard Worker 		_print_timer(f, "hold_timer", tb[IFLA_BRPORT_HOLD_TIMER]);
195*de1e4e89SAndroid Build Coastguard Worker 
196*de1e4e89SAndroid Build Coastguard Worker 	if (tb[IFLA_BRPORT_MESSAGE_AGE_TIMER])
197*de1e4e89SAndroid Build Coastguard Worker 		_print_timer(f, "message_age_timer",
198*de1e4e89SAndroid Build Coastguard Worker 			     tb[IFLA_BRPORT_MESSAGE_AGE_TIMER]);
199*de1e4e89SAndroid Build Coastguard Worker 
200*de1e4e89SAndroid Build Coastguard Worker 	if (tb[IFLA_BRPORT_FORWARD_DELAY_TIMER])
201*de1e4e89SAndroid Build Coastguard Worker 		_print_timer(f, "forward_delay_timer",
202*de1e4e89SAndroid Build Coastguard Worker 			     tb[IFLA_BRPORT_FORWARD_DELAY_TIMER]);
203*de1e4e89SAndroid Build Coastguard Worker 
204*de1e4e89SAndroid Build Coastguard Worker 	if (tb[IFLA_BRPORT_TOPOLOGY_CHANGE_ACK])
205*de1e4e89SAndroid Build Coastguard Worker 		print_uint(PRINT_ANY,
206*de1e4e89SAndroid Build Coastguard Worker 			   "topology_change_ack",
207*de1e4e89SAndroid Build Coastguard Worker 			   "topology_change_ack %u ",
208*de1e4e89SAndroid Build Coastguard Worker 			   rta_getattr_u8(tb[IFLA_BRPORT_TOPOLOGY_CHANGE_ACK]));
209*de1e4e89SAndroid Build Coastguard Worker 
210*de1e4e89SAndroid Build Coastguard Worker 	if (tb[IFLA_BRPORT_CONFIG_PENDING])
211*de1e4e89SAndroid Build Coastguard Worker 		print_uint(PRINT_ANY,
212*de1e4e89SAndroid Build Coastguard Worker 			   "config_pending",
213*de1e4e89SAndroid Build Coastguard Worker 			   "config_pending %u ",
214*de1e4e89SAndroid Build Coastguard Worker 			   rta_getattr_u8(tb[IFLA_BRPORT_CONFIG_PENDING]));
215*de1e4e89SAndroid Build Coastguard Worker 
216*de1e4e89SAndroid Build Coastguard Worker 	if (tb[IFLA_BRPORT_PROXYARP])
217*de1e4e89SAndroid Build Coastguard Worker 		_print_onoff(f, "proxyarp", "proxy_arp",
218*de1e4e89SAndroid Build Coastguard Worker 			     rta_getattr_u8(tb[IFLA_BRPORT_PROXYARP]));
219*de1e4e89SAndroid Build Coastguard Worker 
220*de1e4e89SAndroid Build Coastguard Worker 	if (tb[IFLA_BRPORT_PROXYARP_WIFI])
221*de1e4e89SAndroid Build Coastguard Worker 		_print_onoff(f, "proxyarp_wifi", "proxy_arp_wifi",
222*de1e4e89SAndroid Build Coastguard Worker 			     rta_getattr_u8(tb[IFLA_BRPORT_PROXYARP_WIFI]));
223*de1e4e89SAndroid Build Coastguard Worker 
224*de1e4e89SAndroid Build Coastguard Worker 	if (tb[IFLA_BRPORT_MULTICAST_ROUTER])
225*de1e4e89SAndroid Build Coastguard Worker 		print_uint(PRINT_ANY,
226*de1e4e89SAndroid Build Coastguard Worker 			   "multicast_router",
227*de1e4e89SAndroid Build Coastguard Worker 			   "mcast_router %u ",
228*de1e4e89SAndroid Build Coastguard Worker 			   rta_getattr_u8(tb[IFLA_BRPORT_MULTICAST_ROUTER]));
229*de1e4e89SAndroid Build Coastguard Worker 
230*de1e4e89SAndroid Build Coastguard Worker 	if (tb[IFLA_BRPORT_FAST_LEAVE])
231*de1e4e89SAndroid Build Coastguard Worker 		// not printing any json here because
232*de1e4e89SAndroid Build Coastguard Worker 		// we already printed fast_leave before
233*de1e4e89SAndroid Build Coastguard Worker 		print_string(PRINT_FP,
234*de1e4e89SAndroid Build Coastguard Worker 			     NULL,
235*de1e4e89SAndroid Build Coastguard Worker 			     "mcast_fast_leave %s ",
236*de1e4e89SAndroid Build Coastguard Worker 			     rta_getattr_u8(tb[IFLA_BRPORT_FAST_LEAVE]) ? "on" : "off");
237*de1e4e89SAndroid Build Coastguard Worker 
238*de1e4e89SAndroid Build Coastguard Worker 	if (tb[IFLA_BRPORT_MCAST_FLOOD])
239*de1e4e89SAndroid Build Coastguard Worker 		_print_onoff(f, "mcast_flood", "mcast_flood",
240*de1e4e89SAndroid Build Coastguard Worker 			     rta_getattr_u8(tb[IFLA_BRPORT_MCAST_FLOOD]));
241*de1e4e89SAndroid Build Coastguard Worker }
242*de1e4e89SAndroid Build Coastguard Worker 
bridge_slave_parse_on_off(char * arg_name,char * arg_val,struct nlmsghdr * n,int type)243*de1e4e89SAndroid Build Coastguard Worker static void bridge_slave_parse_on_off(char *arg_name, char *arg_val,
244*de1e4e89SAndroid Build Coastguard Worker 				      struct nlmsghdr *n, int type)
245*de1e4e89SAndroid Build Coastguard Worker {
246*de1e4e89SAndroid Build Coastguard Worker 	__u8 val;
247*de1e4e89SAndroid Build Coastguard Worker 
248*de1e4e89SAndroid Build Coastguard Worker 	if (strcmp(arg_val, "on") == 0)
249*de1e4e89SAndroid Build Coastguard Worker 		val = 1;
250*de1e4e89SAndroid Build Coastguard Worker 	else if (strcmp(arg_val, "off") == 0)
251*de1e4e89SAndroid Build Coastguard Worker 		val = 0;
252*de1e4e89SAndroid Build Coastguard Worker 	else
253*de1e4e89SAndroid Build Coastguard Worker 		invarg("should be \"on\" or \"off\"", arg_name);
254*de1e4e89SAndroid Build Coastguard Worker 
255*de1e4e89SAndroid Build Coastguard Worker 	addattr8(n, 1024, type, val);
256*de1e4e89SAndroid Build Coastguard Worker }
257*de1e4e89SAndroid Build Coastguard Worker 
bridge_slave_parse_opt(struct link_util * lu,int argc,char ** argv,struct nlmsghdr * n)258*de1e4e89SAndroid Build Coastguard Worker static int bridge_slave_parse_opt(struct link_util *lu, int argc, char **argv,
259*de1e4e89SAndroid Build Coastguard Worker 				  struct nlmsghdr *n)
260*de1e4e89SAndroid Build Coastguard Worker {
261*de1e4e89SAndroid Build Coastguard Worker 	__u8 state;
262*de1e4e89SAndroid Build Coastguard Worker 	__u16 priority;
263*de1e4e89SAndroid Build Coastguard Worker 	__u32 cost;
264*de1e4e89SAndroid Build Coastguard Worker 
265*de1e4e89SAndroid Build Coastguard Worker 	while (argc > 0) {
266*de1e4e89SAndroid Build Coastguard Worker 		if (matches(*argv, "fdb_flush") == 0) {
267*de1e4e89SAndroid Build Coastguard Worker 			addattr(n, 1024, IFLA_BRPORT_FLUSH);
268*de1e4e89SAndroid Build Coastguard Worker 		} else if (matches(*argv, "state") == 0) {
269*de1e4e89SAndroid Build Coastguard Worker 			NEXT_ARG();
270*de1e4e89SAndroid Build Coastguard Worker 			if (get_u8(&state, *argv, 0))
271*de1e4e89SAndroid Build Coastguard Worker 				invarg("state is invalid", *argv);
272*de1e4e89SAndroid Build Coastguard Worker 			addattr8(n, 1024, IFLA_BRPORT_STATE, state);
273*de1e4e89SAndroid Build Coastguard Worker 		} else if (matches(*argv, "priority") == 0) {
274*de1e4e89SAndroid Build Coastguard Worker 			NEXT_ARG();
275*de1e4e89SAndroid Build Coastguard Worker 			if (get_u16(&priority, *argv, 0))
276*de1e4e89SAndroid Build Coastguard Worker 				invarg("priority is invalid", *argv);
277*de1e4e89SAndroid Build Coastguard Worker 			addattr16(n, 1024, IFLA_BRPORT_PRIORITY, priority);
278*de1e4e89SAndroid Build Coastguard Worker 		} else if (matches(*argv, "cost") == 0) {
279*de1e4e89SAndroid Build Coastguard Worker 			NEXT_ARG();
280*de1e4e89SAndroid Build Coastguard Worker 			if (get_u32(&cost, *argv, 0))
281*de1e4e89SAndroid Build Coastguard Worker 				invarg("cost is invalid", *argv);
282*de1e4e89SAndroid Build Coastguard Worker 			addattr32(n, 1024, IFLA_BRPORT_COST, cost);
283*de1e4e89SAndroid Build Coastguard Worker 		} else if (matches(*argv, "hairpin") == 0) {
284*de1e4e89SAndroid Build Coastguard Worker 			NEXT_ARG();
285*de1e4e89SAndroid Build Coastguard Worker 			bridge_slave_parse_on_off("hairpin", *argv, n,
286*de1e4e89SAndroid Build Coastguard Worker 						  IFLA_BRPORT_MODE);
287*de1e4e89SAndroid Build Coastguard Worker 		} else if (matches(*argv, "guard") == 0) {
288*de1e4e89SAndroid Build Coastguard Worker 			NEXT_ARG();
289*de1e4e89SAndroid Build Coastguard Worker 			bridge_slave_parse_on_off("guard", *argv, n,
290*de1e4e89SAndroid Build Coastguard Worker 						  IFLA_BRPORT_GUARD);
291*de1e4e89SAndroid Build Coastguard Worker 		} else if (matches(*argv, "root_block") == 0) {
292*de1e4e89SAndroid Build Coastguard Worker 			NEXT_ARG();
293*de1e4e89SAndroid Build Coastguard Worker 			bridge_slave_parse_on_off("root_block", *argv, n,
294*de1e4e89SAndroid Build Coastguard Worker 						  IFLA_BRPORT_PROTECT);
295*de1e4e89SAndroid Build Coastguard Worker 		} else if (matches(*argv, "fastleave") == 0) {
296*de1e4e89SAndroid Build Coastguard Worker 			NEXT_ARG();
297*de1e4e89SAndroid Build Coastguard Worker 			bridge_slave_parse_on_off("fastleave", *argv, n,
298*de1e4e89SAndroid Build Coastguard Worker 						  IFLA_BRPORT_FAST_LEAVE);
299*de1e4e89SAndroid Build Coastguard Worker 		} else if (matches(*argv, "learning") == 0) {
300*de1e4e89SAndroid Build Coastguard Worker 			NEXT_ARG();
301*de1e4e89SAndroid Build Coastguard Worker 			bridge_slave_parse_on_off("learning", *argv, n,
302*de1e4e89SAndroid Build Coastguard Worker 						  IFLA_BRPORT_LEARNING);
303*de1e4e89SAndroid Build Coastguard Worker 		} else if (matches(*argv, "flood") == 0) {
304*de1e4e89SAndroid Build Coastguard Worker 			NEXT_ARG();
305*de1e4e89SAndroid Build Coastguard Worker 			bridge_slave_parse_on_off("flood", *argv, n,
306*de1e4e89SAndroid Build Coastguard Worker 						  IFLA_BRPORT_UNICAST_FLOOD);
307*de1e4e89SAndroid Build Coastguard Worker 		} else if (matches(*argv, "mcast_flood") == 0) {
308*de1e4e89SAndroid Build Coastguard Worker 			NEXT_ARG();
309*de1e4e89SAndroid Build Coastguard Worker 			bridge_slave_parse_on_off("mcast_flood", *argv, n,
310*de1e4e89SAndroid Build Coastguard Worker 						  IFLA_BRPORT_MCAST_FLOOD);
311*de1e4e89SAndroid Build Coastguard Worker 		} else if (matches(*argv, "proxy_arp") == 0) {
312*de1e4e89SAndroid Build Coastguard Worker 			NEXT_ARG();
313*de1e4e89SAndroid Build Coastguard Worker 			bridge_slave_parse_on_off("proxy_arp", *argv, n,
314*de1e4e89SAndroid Build Coastguard Worker 						  IFLA_BRPORT_PROXYARP);
315*de1e4e89SAndroid Build Coastguard Worker 		} else if (matches(*argv, "proxy_arp_wifi") == 0) {
316*de1e4e89SAndroid Build Coastguard Worker 			NEXT_ARG();
317*de1e4e89SAndroid Build Coastguard Worker 			bridge_slave_parse_on_off("proxy_arp_wifi", *argv, n,
318*de1e4e89SAndroid Build Coastguard Worker 						  IFLA_BRPORT_PROXYARP_WIFI);
319*de1e4e89SAndroid Build Coastguard Worker 		} else if (matches(*argv, "mcast_router") == 0) {
320*de1e4e89SAndroid Build Coastguard Worker 			__u8 mcast_router;
321*de1e4e89SAndroid Build Coastguard Worker 
322*de1e4e89SAndroid Build Coastguard Worker 			NEXT_ARG();
323*de1e4e89SAndroid Build Coastguard Worker 			if (get_u8(&mcast_router, *argv, 0))
324*de1e4e89SAndroid Build Coastguard Worker 				invarg("invalid mcast_router", *argv);
325*de1e4e89SAndroid Build Coastguard Worker 			addattr8(n, 1024, IFLA_BRPORT_MULTICAST_ROUTER,
326*de1e4e89SAndroid Build Coastguard Worker 				 mcast_router);
327*de1e4e89SAndroid Build Coastguard Worker 		} else if (matches(*argv, "mcast_fast_leave") == 0) {
328*de1e4e89SAndroid Build Coastguard Worker 			NEXT_ARG();
329*de1e4e89SAndroid Build Coastguard Worker 			bridge_slave_parse_on_off("mcast_fast_leave", *argv, n,
330*de1e4e89SAndroid Build Coastguard Worker 						  IFLA_BRPORT_FAST_LEAVE);
331*de1e4e89SAndroid Build Coastguard Worker 		} else if (matches(*argv, "help") == 0) {
332*de1e4e89SAndroid Build Coastguard Worker 			explain();
333*de1e4e89SAndroid Build Coastguard Worker 			return -1;
334*de1e4e89SAndroid Build Coastguard Worker 		} else {
335*de1e4e89SAndroid Build Coastguard Worker 			fprintf(stderr, "bridge_slave: unknown option \"%s\"?\n",
336*de1e4e89SAndroid Build Coastguard Worker 				*argv);
337*de1e4e89SAndroid Build Coastguard Worker 			explain();
338*de1e4e89SAndroid Build Coastguard Worker 			return -1;
339*de1e4e89SAndroid Build Coastguard Worker 		}
340*de1e4e89SAndroid Build Coastguard Worker 		argc--, argv++;
341*de1e4e89SAndroid Build Coastguard Worker 	}
342*de1e4e89SAndroid Build Coastguard Worker 
343*de1e4e89SAndroid Build Coastguard Worker 	return 0;
344*de1e4e89SAndroid Build Coastguard Worker }
345*de1e4e89SAndroid Build Coastguard Worker 
bridge_slave_print_help(struct link_util * lu,int argc,char ** argv,FILE * f)346*de1e4e89SAndroid Build Coastguard Worker static void bridge_slave_print_help(struct link_util *lu, int argc, char **argv,
347*de1e4e89SAndroid Build Coastguard Worker 		FILE *f)
348*de1e4e89SAndroid Build Coastguard Worker {
349*de1e4e89SAndroid Build Coastguard Worker 	print_explain(f);
350*de1e4e89SAndroid Build Coastguard Worker }
351*de1e4e89SAndroid Build Coastguard Worker 
352*de1e4e89SAndroid Build Coastguard Worker struct link_util bridge_slave_link_util = {
353*de1e4e89SAndroid Build Coastguard Worker 	.id		= "bridge_slave",
354*de1e4e89SAndroid Build Coastguard Worker 	.maxattr	= IFLA_BRPORT_MAX,
355*de1e4e89SAndroid Build Coastguard Worker 	.print_opt	= bridge_slave_print_opt,
356*de1e4e89SAndroid Build Coastguard Worker 	.parse_opt	= bridge_slave_parse_opt,
357*de1e4e89SAndroid Build Coastguard Worker 	.print_help     = bridge_slave_print_help,
358*de1e4e89SAndroid Build Coastguard Worker 	.parse_ifla_xstats = bridge_parse_xstats,
359*de1e4e89SAndroid Build Coastguard Worker 	.print_ifla_xstats = bridge_print_xstats,
360*de1e4e89SAndroid Build Coastguard Worker };
361