xref: /aosp_15_r20/external/iproute2/ip/iplink_bond.c (revision de1e4e894b0c224df933550f0afdecc354b238c4)
1*de1e4e89SAndroid Build Coastguard Worker /*
2*de1e4e89SAndroid Build Coastguard Worker  * iplink_bond.c	Bonding 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  *              Scott Feldman <[email protected]>
11*de1e4e89SAndroid Build Coastguard Worker  */
12*de1e4e89SAndroid Build Coastguard Worker 
13*de1e4e89SAndroid Build Coastguard Worker #include <stdio.h>
14*de1e4e89SAndroid Build Coastguard Worker #include <stdlib.h>
15*de1e4e89SAndroid Build Coastguard Worker #include <string.h>
16*de1e4e89SAndroid Build Coastguard Worker #include <linux/if_link.h>
17*de1e4e89SAndroid Build Coastguard Worker #include <linux/if_ether.h>
18*de1e4e89SAndroid Build Coastguard Worker #include <net/if.h>
19*de1e4e89SAndroid Build Coastguard Worker 
20*de1e4e89SAndroid Build Coastguard Worker #include "rt_names.h"
21*de1e4e89SAndroid Build Coastguard Worker #include "utils.h"
22*de1e4e89SAndroid Build Coastguard Worker #include "ip_common.h"
23*de1e4e89SAndroid Build Coastguard Worker 
24*de1e4e89SAndroid Build Coastguard Worker #define BOND_MAX_ARP_TARGETS    16
25*de1e4e89SAndroid Build Coastguard Worker 
26*de1e4e89SAndroid Build Coastguard Worker static const char *mode_tbl[] = {
27*de1e4e89SAndroid Build Coastguard Worker 	"balance-rr",
28*de1e4e89SAndroid Build Coastguard Worker 	"active-backup",
29*de1e4e89SAndroid Build Coastguard Worker 	"balance-xor",
30*de1e4e89SAndroid Build Coastguard Worker 	"broadcast",
31*de1e4e89SAndroid Build Coastguard Worker 	"802.3ad",
32*de1e4e89SAndroid Build Coastguard Worker 	"balance-tlb",
33*de1e4e89SAndroid Build Coastguard Worker 	"balance-alb",
34*de1e4e89SAndroid Build Coastguard Worker 	NULL,
35*de1e4e89SAndroid Build Coastguard Worker };
36*de1e4e89SAndroid Build Coastguard Worker 
37*de1e4e89SAndroid Build Coastguard Worker static const char *arp_validate_tbl[] = {
38*de1e4e89SAndroid Build Coastguard Worker 	"none",
39*de1e4e89SAndroid Build Coastguard Worker 	"active",
40*de1e4e89SAndroid Build Coastguard Worker 	"backup",
41*de1e4e89SAndroid Build Coastguard Worker 	"all",
42*de1e4e89SAndroid Build Coastguard Worker 	NULL,
43*de1e4e89SAndroid Build Coastguard Worker };
44*de1e4e89SAndroid Build Coastguard Worker 
45*de1e4e89SAndroid Build Coastguard Worker static const char *arp_all_targets_tbl[] = {
46*de1e4e89SAndroid Build Coastguard Worker 	"any",
47*de1e4e89SAndroid Build Coastguard Worker 	"all",
48*de1e4e89SAndroid Build Coastguard Worker 	NULL,
49*de1e4e89SAndroid Build Coastguard Worker };
50*de1e4e89SAndroid Build Coastguard Worker 
51*de1e4e89SAndroid Build Coastguard Worker static const char *primary_reselect_tbl[] = {
52*de1e4e89SAndroid Build Coastguard Worker 	"always",
53*de1e4e89SAndroid Build Coastguard Worker 	"better",
54*de1e4e89SAndroid Build Coastguard Worker 	"failure",
55*de1e4e89SAndroid Build Coastguard Worker 	NULL,
56*de1e4e89SAndroid Build Coastguard Worker };
57*de1e4e89SAndroid Build Coastguard Worker 
58*de1e4e89SAndroid Build Coastguard Worker static const char *fail_over_mac_tbl[] = {
59*de1e4e89SAndroid Build Coastguard Worker 	"none",
60*de1e4e89SAndroid Build Coastguard Worker 	"active",
61*de1e4e89SAndroid Build Coastguard Worker 	"follow",
62*de1e4e89SAndroid Build Coastguard Worker 	NULL,
63*de1e4e89SAndroid Build Coastguard Worker };
64*de1e4e89SAndroid Build Coastguard Worker 
65*de1e4e89SAndroid Build Coastguard Worker static const char *xmit_hash_policy_tbl[] = {
66*de1e4e89SAndroid Build Coastguard Worker 	"layer2",
67*de1e4e89SAndroid Build Coastguard Worker 	"layer3+4",
68*de1e4e89SAndroid Build Coastguard Worker 	"layer2+3",
69*de1e4e89SAndroid Build Coastguard Worker 	"encap2+3",
70*de1e4e89SAndroid Build Coastguard Worker 	"encap3+4",
71*de1e4e89SAndroid Build Coastguard Worker 	NULL,
72*de1e4e89SAndroid Build Coastguard Worker };
73*de1e4e89SAndroid Build Coastguard Worker 
74*de1e4e89SAndroid Build Coastguard Worker static const char *lacp_rate_tbl[] = {
75*de1e4e89SAndroid Build Coastguard Worker 	"slow",
76*de1e4e89SAndroid Build Coastguard Worker 	"fast",
77*de1e4e89SAndroid Build Coastguard Worker 	NULL,
78*de1e4e89SAndroid Build Coastguard Worker };
79*de1e4e89SAndroid Build Coastguard Worker 
80*de1e4e89SAndroid Build Coastguard Worker static const char *ad_select_tbl[] = {
81*de1e4e89SAndroid Build Coastguard Worker 	"stable",
82*de1e4e89SAndroid Build Coastguard Worker 	"bandwidth",
83*de1e4e89SAndroid Build Coastguard Worker 	"count",
84*de1e4e89SAndroid Build Coastguard Worker 	NULL,
85*de1e4e89SAndroid Build Coastguard Worker };
86*de1e4e89SAndroid Build Coastguard Worker 
get_name(const char ** tbl,int index)87*de1e4e89SAndroid Build Coastguard Worker static const char *get_name(const char **tbl, int index)
88*de1e4e89SAndroid Build Coastguard Worker {
89*de1e4e89SAndroid Build Coastguard Worker 	int i;
90*de1e4e89SAndroid Build Coastguard Worker 
91*de1e4e89SAndroid Build Coastguard Worker 	for (i = 0; tbl[i]; i++)
92*de1e4e89SAndroid Build Coastguard Worker 		if (i == index)
93*de1e4e89SAndroid Build Coastguard Worker 			return tbl[i];
94*de1e4e89SAndroid Build Coastguard Worker 
95*de1e4e89SAndroid Build Coastguard Worker 	return "UNKNOWN";
96*de1e4e89SAndroid Build Coastguard Worker }
97*de1e4e89SAndroid Build Coastguard Worker 
get_index(const char ** tbl,char * name)98*de1e4e89SAndroid Build Coastguard Worker static int get_index(const char **tbl, char *name)
99*de1e4e89SAndroid Build Coastguard Worker {
100*de1e4e89SAndroid Build Coastguard Worker 	int i, index;
101*de1e4e89SAndroid Build Coastguard Worker 
102*de1e4e89SAndroid Build Coastguard Worker 	/* check for integer index passed in instead of name */
103*de1e4e89SAndroid Build Coastguard Worker 	if (get_integer(&index, name, 10) == 0)
104*de1e4e89SAndroid Build Coastguard Worker 		for (i = 0; tbl[i]; i++)
105*de1e4e89SAndroid Build Coastguard Worker 			if (i == index)
106*de1e4e89SAndroid Build Coastguard Worker 				return i;
107*de1e4e89SAndroid Build Coastguard Worker 
108*de1e4e89SAndroid Build Coastguard Worker 	for (i = 0; tbl[i]; i++)
109*de1e4e89SAndroid Build Coastguard Worker 		if (strcmp(tbl[i], name) == 0)
110*de1e4e89SAndroid Build Coastguard Worker 			return i;
111*de1e4e89SAndroid Build Coastguard Worker 
112*de1e4e89SAndroid Build Coastguard Worker 	return -1;
113*de1e4e89SAndroid Build Coastguard Worker }
114*de1e4e89SAndroid Build Coastguard Worker 
print_explain(FILE * f)115*de1e4e89SAndroid Build Coastguard Worker static void print_explain(FILE *f)
116*de1e4e89SAndroid Build Coastguard Worker {
117*de1e4e89SAndroid Build Coastguard Worker 	fprintf(f,
118*de1e4e89SAndroid Build Coastguard Worker 		"Usage: ... bond [ mode BONDMODE ] [ active_slave SLAVE_DEV ]\n"
119*de1e4e89SAndroid Build Coastguard Worker 		"                [ clear_active_slave ] [ miimon MIIMON ]\n"
120*de1e4e89SAndroid Build Coastguard Worker 		"                [ updelay UPDELAY ] [ downdelay DOWNDELAY ]\n"
121*de1e4e89SAndroid Build Coastguard Worker 		"                [ use_carrier USE_CARRIER ]\n"
122*de1e4e89SAndroid Build Coastguard Worker 		"                [ arp_interval ARP_INTERVAL ]\n"
123*de1e4e89SAndroid Build Coastguard Worker 		"                [ arp_validate ARP_VALIDATE ]\n"
124*de1e4e89SAndroid Build Coastguard Worker 		"                [ arp_all_targets ARP_ALL_TARGETS ]\n"
125*de1e4e89SAndroid Build Coastguard Worker 		"                [ arp_ip_target [ ARP_IP_TARGET, ... ] ]\n"
126*de1e4e89SAndroid Build Coastguard Worker 		"                [ primary SLAVE_DEV ]\n"
127*de1e4e89SAndroid Build Coastguard Worker 		"                [ primary_reselect PRIMARY_RESELECT ]\n"
128*de1e4e89SAndroid Build Coastguard Worker 		"                [ fail_over_mac FAIL_OVER_MAC ]\n"
129*de1e4e89SAndroid Build Coastguard Worker 		"                [ xmit_hash_policy XMIT_HASH_POLICY ]\n"
130*de1e4e89SAndroid Build Coastguard Worker 		"                [ resend_igmp RESEND_IGMP ]\n"
131*de1e4e89SAndroid Build Coastguard Worker 		"                [ num_grat_arp|num_unsol_na NUM_GRAT_ARP|NUM_UNSOL_NA ]\n"
132*de1e4e89SAndroid Build Coastguard Worker 		"                [ all_slaves_active ALL_SLAVES_ACTIVE ]\n"
133*de1e4e89SAndroid Build Coastguard Worker 		"                [ min_links MIN_LINKS ]\n"
134*de1e4e89SAndroid Build Coastguard Worker 		"                [ lp_interval LP_INTERVAL ]\n"
135*de1e4e89SAndroid Build Coastguard Worker 		"                [ packets_per_slave PACKETS_PER_SLAVE ]\n"
136*de1e4e89SAndroid Build Coastguard Worker 		"                [ tlb_dynamic_lb TLB_DYNAMIC_LB ]\n"
137*de1e4e89SAndroid Build Coastguard Worker 		"                [ lacp_rate LACP_RATE ]\n"
138*de1e4e89SAndroid Build Coastguard Worker 		"                [ ad_select AD_SELECT ]\n"
139*de1e4e89SAndroid Build Coastguard Worker 		"                [ ad_user_port_key PORTKEY ]\n"
140*de1e4e89SAndroid Build Coastguard Worker 		"                [ ad_actor_sys_prio SYSPRIO ]\n"
141*de1e4e89SAndroid Build Coastguard Worker 		"                [ ad_actor_system LLADDR ]\n"
142*de1e4e89SAndroid Build Coastguard Worker 		"\n"
143*de1e4e89SAndroid Build Coastguard Worker 		"BONDMODE := balance-rr|active-backup|balance-xor|broadcast|802.3ad|balance-tlb|balance-alb\n"
144*de1e4e89SAndroid Build Coastguard Worker 		"ARP_VALIDATE := none|active|backup|all\n"
145*de1e4e89SAndroid Build Coastguard Worker 		"ARP_ALL_TARGETS := any|all\n"
146*de1e4e89SAndroid Build Coastguard Worker 		"PRIMARY_RESELECT := always|better|failure\n"
147*de1e4e89SAndroid Build Coastguard Worker 		"FAIL_OVER_MAC := none|active|follow\n"
148*de1e4e89SAndroid Build Coastguard Worker 		"XMIT_HASH_POLICY := layer2|layer2+3|layer3+4|encap2+3|encap3+4\n"
149*de1e4e89SAndroid Build Coastguard Worker 		"LACP_RATE := slow|fast\n"
150*de1e4e89SAndroid Build Coastguard Worker 		"AD_SELECT := stable|bandwidth|count\n"
151*de1e4e89SAndroid Build Coastguard Worker 	);
152*de1e4e89SAndroid Build Coastguard Worker }
153*de1e4e89SAndroid Build Coastguard Worker 
explain(void)154*de1e4e89SAndroid Build Coastguard Worker static void explain(void)
155*de1e4e89SAndroid Build Coastguard Worker {
156*de1e4e89SAndroid Build Coastguard Worker 	print_explain(stderr);
157*de1e4e89SAndroid Build Coastguard Worker }
158*de1e4e89SAndroid Build Coastguard Worker 
bond_parse_opt(struct link_util * lu,int argc,char ** argv,struct nlmsghdr * n)159*de1e4e89SAndroid Build Coastguard Worker static int bond_parse_opt(struct link_util *lu, int argc, char **argv,
160*de1e4e89SAndroid Build Coastguard Worker 			  struct nlmsghdr *n)
161*de1e4e89SAndroid Build Coastguard Worker {
162*de1e4e89SAndroid Build Coastguard Worker 	__u8 mode, use_carrier, primary_reselect, fail_over_mac;
163*de1e4e89SAndroid Build Coastguard Worker 	__u8 xmit_hash_policy, num_peer_notif, all_slaves_active;
164*de1e4e89SAndroid Build Coastguard Worker 	__u8 lacp_rate, ad_select, tlb_dynamic_lb;
165*de1e4e89SAndroid Build Coastguard Worker 	__u16 ad_user_port_key, ad_actor_sys_prio;
166*de1e4e89SAndroid Build Coastguard Worker 	__u32 miimon, updelay, downdelay, arp_interval, arp_validate;
167*de1e4e89SAndroid Build Coastguard Worker 	__u32 arp_all_targets, resend_igmp, min_links, lp_interval;
168*de1e4e89SAndroid Build Coastguard Worker 	__u32 packets_per_slave;
169*de1e4e89SAndroid Build Coastguard Worker 	unsigned int ifindex;
170*de1e4e89SAndroid Build Coastguard Worker 
171*de1e4e89SAndroid Build Coastguard Worker 	while (argc > 0) {
172*de1e4e89SAndroid Build Coastguard Worker 		if (matches(*argv, "mode") == 0) {
173*de1e4e89SAndroid Build Coastguard Worker 			NEXT_ARG();
174*de1e4e89SAndroid Build Coastguard Worker 			if (get_index(mode_tbl, *argv) < 0)
175*de1e4e89SAndroid Build Coastguard Worker 				invarg("invalid mode", *argv);
176*de1e4e89SAndroid Build Coastguard Worker 			mode = get_index(mode_tbl, *argv);
177*de1e4e89SAndroid Build Coastguard Worker 			addattr8(n, 1024, IFLA_BOND_MODE, mode);
178*de1e4e89SAndroid Build Coastguard Worker 		} else if (matches(*argv, "active_slave") == 0) {
179*de1e4e89SAndroid Build Coastguard Worker 			NEXT_ARG();
180*de1e4e89SAndroid Build Coastguard Worker 			ifindex = if_nametoindex(*argv);
181*de1e4e89SAndroid Build Coastguard Worker 			if (!ifindex)
182*de1e4e89SAndroid Build Coastguard Worker 				return -1;
183*de1e4e89SAndroid Build Coastguard Worker 			addattr32(n, 1024, IFLA_BOND_ACTIVE_SLAVE, ifindex);
184*de1e4e89SAndroid Build Coastguard Worker 		} else if (matches(*argv, "clear_active_slave") == 0) {
185*de1e4e89SAndroid Build Coastguard Worker 			addattr32(n, 1024, IFLA_BOND_ACTIVE_SLAVE, 0);
186*de1e4e89SAndroid Build Coastguard Worker 		} else if (matches(*argv, "miimon") == 0) {
187*de1e4e89SAndroid Build Coastguard Worker 			NEXT_ARG();
188*de1e4e89SAndroid Build Coastguard Worker 			if (get_u32(&miimon, *argv, 0))
189*de1e4e89SAndroid Build Coastguard Worker 				invarg("invalid miimon", *argv);
190*de1e4e89SAndroid Build Coastguard Worker 			addattr32(n, 1024, IFLA_BOND_MIIMON, miimon);
191*de1e4e89SAndroid Build Coastguard Worker 		} else if (matches(*argv, "updelay") == 0) {
192*de1e4e89SAndroid Build Coastguard Worker 			NEXT_ARG();
193*de1e4e89SAndroid Build Coastguard Worker 			if (get_u32(&updelay, *argv, 0))
194*de1e4e89SAndroid Build Coastguard Worker 				invarg("invalid updelay", *argv);
195*de1e4e89SAndroid Build Coastguard Worker 			addattr32(n, 1024, IFLA_BOND_UPDELAY, updelay);
196*de1e4e89SAndroid Build Coastguard Worker 		} else if (matches(*argv, "downdelay") == 0) {
197*de1e4e89SAndroid Build Coastguard Worker 			NEXT_ARG();
198*de1e4e89SAndroid Build Coastguard Worker 			if (get_u32(&downdelay, *argv, 0))
199*de1e4e89SAndroid Build Coastguard Worker 				invarg("invalid downdelay", *argv);
200*de1e4e89SAndroid Build Coastguard Worker 			addattr32(n, 1024, IFLA_BOND_DOWNDELAY, downdelay);
201*de1e4e89SAndroid Build Coastguard Worker 		} else if (matches(*argv, "use_carrier") == 0) {
202*de1e4e89SAndroid Build Coastguard Worker 			NEXT_ARG();
203*de1e4e89SAndroid Build Coastguard Worker 			if (get_u8(&use_carrier, *argv, 0))
204*de1e4e89SAndroid Build Coastguard Worker 				invarg("invalid use_carrier", *argv);
205*de1e4e89SAndroid Build Coastguard Worker 			addattr8(n, 1024, IFLA_BOND_USE_CARRIER, use_carrier);
206*de1e4e89SAndroid Build Coastguard Worker 		} else if (matches(*argv, "arp_interval") == 0) {
207*de1e4e89SAndroid Build Coastguard Worker 			NEXT_ARG();
208*de1e4e89SAndroid Build Coastguard Worker 			if (get_u32(&arp_interval, *argv, 0))
209*de1e4e89SAndroid Build Coastguard Worker 				invarg("invalid arp_interval", *argv);
210*de1e4e89SAndroid Build Coastguard Worker 			addattr32(n, 1024, IFLA_BOND_ARP_INTERVAL, arp_interval);
211*de1e4e89SAndroid Build Coastguard Worker 		} else if (matches(*argv, "arp_ip_target") == 0) {
212*de1e4e89SAndroid Build Coastguard Worker 			struct rtattr *nest = addattr_nest(n, 1024,
213*de1e4e89SAndroid Build Coastguard Worker 				IFLA_BOND_ARP_IP_TARGET);
214*de1e4e89SAndroid Build Coastguard Worker 			if (NEXT_ARG_OK()) {
215*de1e4e89SAndroid Build Coastguard Worker 				NEXT_ARG();
216*de1e4e89SAndroid Build Coastguard Worker 				char *targets = strdupa(*argv);
217*de1e4e89SAndroid Build Coastguard Worker 				char *target = strtok(targets, ",");
218*de1e4e89SAndroid Build Coastguard Worker 				int i;
219*de1e4e89SAndroid Build Coastguard Worker 
220*de1e4e89SAndroid Build Coastguard Worker 				for (i = 0; target && i < BOND_MAX_ARP_TARGETS; i++) {
221*de1e4e89SAndroid Build Coastguard Worker 					__u32 addr = get_addr32(target);
222*de1e4e89SAndroid Build Coastguard Worker 
223*de1e4e89SAndroid Build Coastguard Worker 					addattr32(n, 1024, i, addr);
224*de1e4e89SAndroid Build Coastguard Worker 					target = strtok(NULL, ",");
225*de1e4e89SAndroid Build Coastguard Worker 				}
226*de1e4e89SAndroid Build Coastguard Worker 				addattr_nest_end(n, nest);
227*de1e4e89SAndroid Build Coastguard Worker 			}
228*de1e4e89SAndroid Build Coastguard Worker 			addattr_nest_end(n, nest);
229*de1e4e89SAndroid Build Coastguard Worker 		} else if (matches(*argv, "arp_validate") == 0) {
230*de1e4e89SAndroid Build Coastguard Worker 			NEXT_ARG();
231*de1e4e89SAndroid Build Coastguard Worker 			if (get_index(arp_validate_tbl, *argv) < 0)
232*de1e4e89SAndroid Build Coastguard Worker 				invarg("invalid arp_validate", *argv);
233*de1e4e89SAndroid Build Coastguard Worker 			arp_validate = get_index(arp_validate_tbl, *argv);
234*de1e4e89SAndroid Build Coastguard Worker 			addattr32(n, 1024, IFLA_BOND_ARP_VALIDATE, arp_validate);
235*de1e4e89SAndroid Build Coastguard Worker 		} else if (matches(*argv, "arp_all_targets") == 0) {
236*de1e4e89SAndroid Build Coastguard Worker 			NEXT_ARG();
237*de1e4e89SAndroid Build Coastguard Worker 			if (get_index(arp_all_targets_tbl, *argv) < 0)
238*de1e4e89SAndroid Build Coastguard Worker 				invarg("invalid arp_all_targets", *argv);
239*de1e4e89SAndroid Build Coastguard Worker 			arp_all_targets = get_index(arp_all_targets_tbl, *argv);
240*de1e4e89SAndroid Build Coastguard Worker 			addattr32(n, 1024, IFLA_BOND_ARP_ALL_TARGETS, arp_all_targets);
241*de1e4e89SAndroid Build Coastguard Worker 		} else if (matches(*argv, "primary") == 0) {
242*de1e4e89SAndroid Build Coastguard Worker 			NEXT_ARG();
243*de1e4e89SAndroid Build Coastguard Worker 			ifindex = if_nametoindex(*argv);
244*de1e4e89SAndroid Build Coastguard Worker 			if (!ifindex)
245*de1e4e89SAndroid Build Coastguard Worker 				return -1;
246*de1e4e89SAndroid Build Coastguard Worker 			addattr32(n, 1024, IFLA_BOND_PRIMARY, ifindex);
247*de1e4e89SAndroid Build Coastguard Worker 		} else if (matches(*argv, "primary_reselect") == 0) {
248*de1e4e89SAndroid Build Coastguard Worker 			NEXT_ARG();
249*de1e4e89SAndroid Build Coastguard Worker 			if (get_index(primary_reselect_tbl, *argv) < 0)
250*de1e4e89SAndroid Build Coastguard Worker 				invarg("invalid primary_reselect", *argv);
251*de1e4e89SAndroid Build Coastguard Worker 			primary_reselect = get_index(primary_reselect_tbl, *argv);
252*de1e4e89SAndroid Build Coastguard Worker 			addattr8(n, 1024, IFLA_BOND_PRIMARY_RESELECT,
253*de1e4e89SAndroid Build Coastguard Worker 				 primary_reselect);
254*de1e4e89SAndroid Build Coastguard Worker 		} else if (matches(*argv, "fail_over_mac") == 0) {
255*de1e4e89SAndroid Build Coastguard Worker 			NEXT_ARG();
256*de1e4e89SAndroid Build Coastguard Worker 			if (get_index(fail_over_mac_tbl, *argv) < 0)
257*de1e4e89SAndroid Build Coastguard Worker 				invarg("invalid fail_over_mac", *argv);
258*de1e4e89SAndroid Build Coastguard Worker 			fail_over_mac = get_index(fail_over_mac_tbl, *argv);
259*de1e4e89SAndroid Build Coastguard Worker 			addattr8(n, 1024, IFLA_BOND_FAIL_OVER_MAC,
260*de1e4e89SAndroid Build Coastguard Worker 				 fail_over_mac);
261*de1e4e89SAndroid Build Coastguard Worker 		} else if (matches(*argv, "xmit_hash_policy") == 0) {
262*de1e4e89SAndroid Build Coastguard Worker 			NEXT_ARG();
263*de1e4e89SAndroid Build Coastguard Worker 			if (get_index(xmit_hash_policy_tbl, *argv) < 0)
264*de1e4e89SAndroid Build Coastguard Worker 				invarg("invalid xmit_hash_policy", *argv);
265*de1e4e89SAndroid Build Coastguard Worker 
266*de1e4e89SAndroid Build Coastguard Worker 			xmit_hash_policy = get_index(xmit_hash_policy_tbl, *argv);
267*de1e4e89SAndroid Build Coastguard Worker 			addattr8(n, 1024, IFLA_BOND_XMIT_HASH_POLICY,
268*de1e4e89SAndroid Build Coastguard Worker 				 xmit_hash_policy);
269*de1e4e89SAndroid Build Coastguard Worker 		} else if (matches(*argv, "resend_igmp") == 0) {
270*de1e4e89SAndroid Build Coastguard Worker 			NEXT_ARG();
271*de1e4e89SAndroid Build Coastguard Worker 			if (get_u32(&resend_igmp, *argv, 0))
272*de1e4e89SAndroid Build Coastguard Worker 				invarg("invalid resend_igmp", *argv);
273*de1e4e89SAndroid Build Coastguard Worker 
274*de1e4e89SAndroid Build Coastguard Worker 			addattr32(n, 1024, IFLA_BOND_RESEND_IGMP, resend_igmp);
275*de1e4e89SAndroid Build Coastguard Worker 		} else if (matches(*argv, "num_grat_arp") == 0 ||
276*de1e4e89SAndroid Build Coastguard Worker 			   matches(*argv, "num_unsol_na") == 0) {
277*de1e4e89SAndroid Build Coastguard Worker 			NEXT_ARG();
278*de1e4e89SAndroid Build Coastguard Worker 			if (get_u8(&num_peer_notif, *argv, 0))
279*de1e4e89SAndroid Build Coastguard Worker 				invarg("invalid num_grat_arp|num_unsol_na",
280*de1e4e89SAndroid Build Coastguard Worker 				       *argv);
281*de1e4e89SAndroid Build Coastguard Worker 
282*de1e4e89SAndroid Build Coastguard Worker 			addattr8(n, 1024, IFLA_BOND_NUM_PEER_NOTIF,
283*de1e4e89SAndroid Build Coastguard Worker 				 num_peer_notif);
284*de1e4e89SAndroid Build Coastguard Worker 		} else if (matches(*argv, "all_slaves_active") == 0) {
285*de1e4e89SAndroid Build Coastguard Worker 			NEXT_ARG();
286*de1e4e89SAndroid Build Coastguard Worker 			if (get_u8(&all_slaves_active, *argv, 0))
287*de1e4e89SAndroid Build Coastguard Worker 				invarg("invalid all_slaves_active", *argv);
288*de1e4e89SAndroid Build Coastguard Worker 
289*de1e4e89SAndroid Build Coastguard Worker 			addattr8(n, 1024, IFLA_BOND_ALL_SLAVES_ACTIVE,
290*de1e4e89SAndroid Build Coastguard Worker 				 all_slaves_active);
291*de1e4e89SAndroid Build Coastguard Worker 		} else if (matches(*argv, "min_links") == 0) {
292*de1e4e89SAndroid Build Coastguard Worker 			NEXT_ARG();
293*de1e4e89SAndroid Build Coastguard Worker 			if (get_u32(&min_links, *argv, 0))
294*de1e4e89SAndroid Build Coastguard Worker 				invarg("invalid min_links", *argv);
295*de1e4e89SAndroid Build Coastguard Worker 
296*de1e4e89SAndroid Build Coastguard Worker 			addattr32(n, 1024, IFLA_BOND_MIN_LINKS, min_links);
297*de1e4e89SAndroid Build Coastguard Worker 		} else if (matches(*argv, "lp_interval") == 0) {
298*de1e4e89SAndroid Build Coastguard Worker 			NEXT_ARG();
299*de1e4e89SAndroid Build Coastguard Worker 			if (get_u32(&lp_interval, *argv, 0))
300*de1e4e89SAndroid Build Coastguard Worker 				invarg("invalid lp_interval", *argv);
301*de1e4e89SAndroid Build Coastguard Worker 
302*de1e4e89SAndroid Build Coastguard Worker 			addattr32(n, 1024, IFLA_BOND_LP_INTERVAL, lp_interval);
303*de1e4e89SAndroid Build Coastguard Worker 		} else if (matches(*argv, "packets_per_slave") == 0) {
304*de1e4e89SAndroid Build Coastguard Worker 			NEXT_ARG();
305*de1e4e89SAndroid Build Coastguard Worker 			if (get_u32(&packets_per_slave, *argv, 0))
306*de1e4e89SAndroid Build Coastguard Worker 				invarg("invalid packets_per_slave", *argv);
307*de1e4e89SAndroid Build Coastguard Worker 
308*de1e4e89SAndroid Build Coastguard Worker 			addattr32(n, 1024, IFLA_BOND_PACKETS_PER_SLAVE,
309*de1e4e89SAndroid Build Coastguard Worker 				  packets_per_slave);
310*de1e4e89SAndroid Build Coastguard Worker 		} else if (matches(*argv, "lacp_rate") == 0) {
311*de1e4e89SAndroid Build Coastguard Worker 			NEXT_ARG();
312*de1e4e89SAndroid Build Coastguard Worker 			if (get_index(lacp_rate_tbl, *argv) < 0)
313*de1e4e89SAndroid Build Coastguard Worker 				invarg("invalid lacp_rate", *argv);
314*de1e4e89SAndroid Build Coastguard Worker 
315*de1e4e89SAndroid Build Coastguard Worker 			lacp_rate = get_index(lacp_rate_tbl, *argv);
316*de1e4e89SAndroid Build Coastguard Worker 			addattr8(n, 1024, IFLA_BOND_AD_LACP_RATE, lacp_rate);
317*de1e4e89SAndroid Build Coastguard Worker 		} else if (matches(*argv, "ad_select") == 0) {
318*de1e4e89SAndroid Build Coastguard Worker 			NEXT_ARG();
319*de1e4e89SAndroid Build Coastguard Worker 			if (get_index(ad_select_tbl, *argv) < 0)
320*de1e4e89SAndroid Build Coastguard Worker 				invarg("invalid ad_select", *argv);
321*de1e4e89SAndroid Build Coastguard Worker 
322*de1e4e89SAndroid Build Coastguard Worker 			ad_select = get_index(ad_select_tbl, *argv);
323*de1e4e89SAndroid Build Coastguard Worker 			addattr8(n, 1024, IFLA_BOND_AD_SELECT, ad_select);
324*de1e4e89SAndroid Build Coastguard Worker 		} else if (matches(*argv, "ad_user_port_key") == 0) {
325*de1e4e89SAndroid Build Coastguard Worker 			NEXT_ARG();
326*de1e4e89SAndroid Build Coastguard Worker 			if (get_u16(&ad_user_port_key, *argv, 0))
327*de1e4e89SAndroid Build Coastguard Worker 				invarg("invalid ad_user_port_key", *argv);
328*de1e4e89SAndroid Build Coastguard Worker 
329*de1e4e89SAndroid Build Coastguard Worker 			addattr16(n, 1024, IFLA_BOND_AD_USER_PORT_KEY,
330*de1e4e89SAndroid Build Coastguard Worker 				  ad_user_port_key);
331*de1e4e89SAndroid Build Coastguard Worker 		} else if (matches(*argv, "ad_actor_sys_prio") == 0) {
332*de1e4e89SAndroid Build Coastguard Worker 			NEXT_ARG();
333*de1e4e89SAndroid Build Coastguard Worker 			if (get_u16(&ad_actor_sys_prio, *argv, 0))
334*de1e4e89SAndroid Build Coastguard Worker 				invarg("invalid ad_actor_sys_prio", *argv);
335*de1e4e89SAndroid Build Coastguard Worker 
336*de1e4e89SAndroid Build Coastguard Worker 			addattr16(n, 1024, IFLA_BOND_AD_ACTOR_SYS_PRIO,
337*de1e4e89SAndroid Build Coastguard Worker 				  ad_actor_sys_prio);
338*de1e4e89SAndroid Build Coastguard Worker 		} else if (matches(*argv, "ad_actor_system") == 0) {
339*de1e4e89SAndroid Build Coastguard Worker 			int len;
340*de1e4e89SAndroid Build Coastguard Worker 			char abuf[32];
341*de1e4e89SAndroid Build Coastguard Worker 
342*de1e4e89SAndroid Build Coastguard Worker 			NEXT_ARG();
343*de1e4e89SAndroid Build Coastguard Worker 			len = ll_addr_a2n(abuf, sizeof(abuf), *argv);
344*de1e4e89SAndroid Build Coastguard Worker 			if (len < 0)
345*de1e4e89SAndroid Build Coastguard Worker 				return -1;
346*de1e4e89SAndroid Build Coastguard Worker 			addattr_l(n, 1024, IFLA_BOND_AD_ACTOR_SYSTEM,
347*de1e4e89SAndroid Build Coastguard Worker 				  abuf, len);
348*de1e4e89SAndroid Build Coastguard Worker 		} else if (matches(*argv, "tlb_dynamic_lb") == 0) {
349*de1e4e89SAndroid Build Coastguard Worker 			NEXT_ARG();
350*de1e4e89SAndroid Build Coastguard Worker 			if (get_u8(&tlb_dynamic_lb, *argv, 0)) {
351*de1e4e89SAndroid Build Coastguard Worker 				invarg("invalid tlb_dynamic_lb", *argv);
352*de1e4e89SAndroid Build Coastguard Worker 				return -1;
353*de1e4e89SAndroid Build Coastguard Worker 			}
354*de1e4e89SAndroid Build Coastguard Worker 			addattr8(n, 1024, IFLA_BOND_TLB_DYNAMIC_LB,
355*de1e4e89SAndroid Build Coastguard Worker 				 tlb_dynamic_lb);
356*de1e4e89SAndroid Build Coastguard Worker 		} else if (matches(*argv, "help") == 0) {
357*de1e4e89SAndroid Build Coastguard Worker 			explain();
358*de1e4e89SAndroid Build Coastguard Worker 			return -1;
359*de1e4e89SAndroid Build Coastguard Worker 		} else {
360*de1e4e89SAndroid Build Coastguard Worker 			fprintf(stderr, "bond: unknown command \"%s\"?\n", *argv);
361*de1e4e89SAndroid Build Coastguard Worker 			explain();
362*de1e4e89SAndroid Build Coastguard Worker 			return -1;
363*de1e4e89SAndroid Build Coastguard Worker 		}
364*de1e4e89SAndroid Build Coastguard Worker 		argc--, argv++;
365*de1e4e89SAndroid Build Coastguard Worker 	}
366*de1e4e89SAndroid Build Coastguard Worker 
367*de1e4e89SAndroid Build Coastguard Worker 	return 0;
368*de1e4e89SAndroid Build Coastguard Worker }
369*de1e4e89SAndroid Build Coastguard Worker 
bond_print_opt(struct link_util * lu,FILE * f,struct rtattr * tb[])370*de1e4e89SAndroid Build Coastguard Worker static void bond_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb[])
371*de1e4e89SAndroid Build Coastguard Worker {
372*de1e4e89SAndroid Build Coastguard Worker 	unsigned int ifindex;
373*de1e4e89SAndroid Build Coastguard Worker 
374*de1e4e89SAndroid Build Coastguard Worker 	if (!tb)
375*de1e4e89SAndroid Build Coastguard Worker 		return;
376*de1e4e89SAndroid Build Coastguard Worker 
377*de1e4e89SAndroid Build Coastguard Worker 	if (tb[IFLA_BOND_MODE]) {
378*de1e4e89SAndroid Build Coastguard Worker 		const char *mode = get_name(mode_tbl,
379*de1e4e89SAndroid Build Coastguard Worker 					    rta_getattr_u8(tb[IFLA_BOND_MODE]));
380*de1e4e89SAndroid Build Coastguard Worker 		print_string(PRINT_ANY, "mode", "mode %s ", mode);
381*de1e4e89SAndroid Build Coastguard Worker 	}
382*de1e4e89SAndroid Build Coastguard Worker 
383*de1e4e89SAndroid Build Coastguard Worker 	if (tb[IFLA_BOND_ACTIVE_SLAVE] &&
384*de1e4e89SAndroid Build Coastguard Worker 	    (ifindex = rta_getattr_u32(tb[IFLA_BOND_ACTIVE_SLAVE]))) {
385*de1e4e89SAndroid Build Coastguard Worker 		char buf[IFNAMSIZ];
386*de1e4e89SAndroid Build Coastguard Worker 		const char *n = if_indextoname(ifindex, buf);
387*de1e4e89SAndroid Build Coastguard Worker 
388*de1e4e89SAndroid Build Coastguard Worker 		if (n)
389*de1e4e89SAndroid Build Coastguard Worker 			print_string(PRINT_ANY,
390*de1e4e89SAndroid Build Coastguard Worker 				     "active_slave",
391*de1e4e89SAndroid Build Coastguard Worker 				     "active_slave %s ",
392*de1e4e89SAndroid Build Coastguard Worker 				     n);
393*de1e4e89SAndroid Build Coastguard Worker 		else
394*de1e4e89SAndroid Build Coastguard Worker 			print_uint(PRINT_ANY,
395*de1e4e89SAndroid Build Coastguard Worker 				   "active_slave_index",
396*de1e4e89SAndroid Build Coastguard Worker 				   "active_slave %u ",
397*de1e4e89SAndroid Build Coastguard Worker 				   ifindex);
398*de1e4e89SAndroid Build Coastguard Worker 	}
399*de1e4e89SAndroid Build Coastguard Worker 
400*de1e4e89SAndroid Build Coastguard Worker 	if (tb[IFLA_BOND_MIIMON])
401*de1e4e89SAndroid Build Coastguard Worker 		print_uint(PRINT_ANY,
402*de1e4e89SAndroid Build Coastguard Worker 			   "miimon",
403*de1e4e89SAndroid Build Coastguard Worker 			   "miimon %u ",
404*de1e4e89SAndroid Build Coastguard Worker 			   rta_getattr_u32(tb[IFLA_BOND_MIIMON]));
405*de1e4e89SAndroid Build Coastguard Worker 
406*de1e4e89SAndroid Build Coastguard Worker 	if (tb[IFLA_BOND_UPDELAY])
407*de1e4e89SAndroid Build Coastguard Worker 		print_uint(PRINT_ANY,
408*de1e4e89SAndroid Build Coastguard Worker 			   "updelay",
409*de1e4e89SAndroid Build Coastguard Worker 			   "updelay %u ",
410*de1e4e89SAndroid Build Coastguard Worker 			   rta_getattr_u32(tb[IFLA_BOND_UPDELAY]));
411*de1e4e89SAndroid Build Coastguard Worker 
412*de1e4e89SAndroid Build Coastguard Worker 	if (tb[IFLA_BOND_DOWNDELAY])
413*de1e4e89SAndroid Build Coastguard Worker 		print_uint(PRINT_ANY,
414*de1e4e89SAndroid Build Coastguard Worker 			   "downdelay",
415*de1e4e89SAndroid Build Coastguard Worker 			   "downdelay %u ",
416*de1e4e89SAndroid Build Coastguard Worker 			   rta_getattr_u32(tb[IFLA_BOND_DOWNDELAY]));
417*de1e4e89SAndroid Build Coastguard Worker 
418*de1e4e89SAndroid Build Coastguard Worker 	if (tb[IFLA_BOND_USE_CARRIER])
419*de1e4e89SAndroid Build Coastguard Worker 		print_uint(PRINT_ANY,
420*de1e4e89SAndroid Build Coastguard Worker 			   "use_carrier",
421*de1e4e89SAndroid Build Coastguard Worker 			   "use_carrier %u ",
422*de1e4e89SAndroid Build Coastguard Worker 			   rta_getattr_u8(tb[IFLA_BOND_USE_CARRIER]));
423*de1e4e89SAndroid Build Coastguard Worker 
424*de1e4e89SAndroid Build Coastguard Worker 	if (tb[IFLA_BOND_ARP_INTERVAL])
425*de1e4e89SAndroid Build Coastguard Worker 		print_uint(PRINT_ANY,
426*de1e4e89SAndroid Build Coastguard Worker 			   "arp_interval",
427*de1e4e89SAndroid Build Coastguard Worker 			   "arp_interval %u ",
428*de1e4e89SAndroid Build Coastguard Worker 			   rta_getattr_u32(tb[IFLA_BOND_ARP_INTERVAL]));
429*de1e4e89SAndroid Build Coastguard Worker 
430*de1e4e89SAndroid Build Coastguard Worker 	if (tb[IFLA_BOND_ARP_IP_TARGET]) {
431*de1e4e89SAndroid Build Coastguard Worker 		struct rtattr *iptb[BOND_MAX_ARP_TARGETS + 1];
432*de1e4e89SAndroid Build Coastguard Worker 		int i;
433*de1e4e89SAndroid Build Coastguard Worker 
434*de1e4e89SAndroid Build Coastguard Worker 		parse_rtattr_nested(iptb, BOND_MAX_ARP_TARGETS,
435*de1e4e89SAndroid Build Coastguard Worker 				    tb[IFLA_BOND_ARP_IP_TARGET]);
436*de1e4e89SAndroid Build Coastguard Worker 
437*de1e4e89SAndroid Build Coastguard Worker 		if (iptb[0]) {
438*de1e4e89SAndroid Build Coastguard Worker 			open_json_array(PRINT_JSON, "arp_ip_target");
439*de1e4e89SAndroid Build Coastguard Worker 			print_string(PRINT_FP, NULL, "arp_ip_target ", NULL);
440*de1e4e89SAndroid Build Coastguard Worker 		}
441*de1e4e89SAndroid Build Coastguard Worker 
442*de1e4e89SAndroid Build Coastguard Worker 		for (i = 0; i < BOND_MAX_ARP_TARGETS; i++) {
443*de1e4e89SAndroid Build Coastguard Worker 			if (iptb[i])
444*de1e4e89SAndroid Build Coastguard Worker 				print_string(PRINT_ANY,
445*de1e4e89SAndroid Build Coastguard Worker 					     NULL,
446*de1e4e89SAndroid Build Coastguard Worker 					     "%s",
447*de1e4e89SAndroid Build Coastguard Worker 					     rt_addr_n2a_rta(AF_INET, iptb[i]));
448*de1e4e89SAndroid Build Coastguard Worker 			if (!is_json_context()
449*de1e4e89SAndroid Build Coastguard Worker 			    && i < BOND_MAX_ARP_TARGETS-1
450*de1e4e89SAndroid Build Coastguard Worker 			    && iptb[i+1])
451*de1e4e89SAndroid Build Coastguard Worker 				fprintf(f, ",");
452*de1e4e89SAndroid Build Coastguard Worker 		}
453*de1e4e89SAndroid Build Coastguard Worker 
454*de1e4e89SAndroid Build Coastguard Worker 		if (iptb[0]) {
455*de1e4e89SAndroid Build Coastguard Worker 			print_string(PRINT_FP, NULL, " ", NULL);
456*de1e4e89SAndroid Build Coastguard Worker 			close_json_array(PRINT_JSON, NULL);
457*de1e4e89SAndroid Build Coastguard Worker 		}
458*de1e4e89SAndroid Build Coastguard Worker 	}
459*de1e4e89SAndroid Build Coastguard Worker 
460*de1e4e89SAndroid Build Coastguard Worker 	if (tb[IFLA_BOND_ARP_VALIDATE]) {
461*de1e4e89SAndroid Build Coastguard Worker 		__u32 arp_v = rta_getattr_u32(tb[IFLA_BOND_ARP_VALIDATE]);
462*de1e4e89SAndroid Build Coastguard Worker 		const char *arp_validate = get_name(arp_validate_tbl, arp_v);
463*de1e4e89SAndroid Build Coastguard Worker 
464*de1e4e89SAndroid Build Coastguard Worker 		if (!arp_v && is_json_context())
465*de1e4e89SAndroid Build Coastguard Worker 			print_null(PRINT_JSON, "arp_validate", NULL, NULL);
466*de1e4e89SAndroid Build Coastguard Worker 		else
467*de1e4e89SAndroid Build Coastguard Worker 			print_string(PRINT_ANY,
468*de1e4e89SAndroid Build Coastguard Worker 				     "arp_validate",
469*de1e4e89SAndroid Build Coastguard Worker 				     "arp_validate %s ",
470*de1e4e89SAndroid Build Coastguard Worker 				     arp_validate);
471*de1e4e89SAndroid Build Coastguard Worker 	}
472*de1e4e89SAndroid Build Coastguard Worker 
473*de1e4e89SAndroid Build Coastguard Worker 	if (tb[IFLA_BOND_ARP_ALL_TARGETS]) {
474*de1e4e89SAndroid Build Coastguard Worker 		const char *arp_all_targets = get_name(arp_all_targets_tbl,
475*de1e4e89SAndroid Build Coastguard Worker 						       rta_getattr_u32(tb[IFLA_BOND_ARP_ALL_TARGETS]));
476*de1e4e89SAndroid Build Coastguard Worker 		print_string(PRINT_ANY,
477*de1e4e89SAndroid Build Coastguard Worker 			     "arp_all_targets",
478*de1e4e89SAndroid Build Coastguard Worker 			     "arp_all_targets %s ",
479*de1e4e89SAndroid Build Coastguard Worker 			     arp_all_targets);
480*de1e4e89SAndroid Build Coastguard Worker 	}
481*de1e4e89SAndroid Build Coastguard Worker 
482*de1e4e89SAndroid Build Coastguard Worker 	if (tb[IFLA_BOND_PRIMARY] &&
483*de1e4e89SAndroid Build Coastguard Worker 	    (ifindex = rta_getattr_u32(tb[IFLA_BOND_PRIMARY]))) {
484*de1e4e89SAndroid Build Coastguard Worker 		char buf[IFNAMSIZ];
485*de1e4e89SAndroid Build Coastguard Worker 		const char *n = if_indextoname(ifindex, buf);
486*de1e4e89SAndroid Build Coastguard Worker 
487*de1e4e89SAndroid Build Coastguard Worker 		if (n)
488*de1e4e89SAndroid Build Coastguard Worker 			print_string(PRINT_ANY, "primary", "primary %s ", n);
489*de1e4e89SAndroid Build Coastguard Worker 		else
490*de1e4e89SAndroid Build Coastguard Worker 			print_uint(PRINT_ANY,
491*de1e4e89SAndroid Build Coastguard Worker 				   "primary_index",
492*de1e4e89SAndroid Build Coastguard Worker 				   "primary %u ",
493*de1e4e89SAndroid Build Coastguard Worker 				   ifindex);
494*de1e4e89SAndroid Build Coastguard Worker 	}
495*de1e4e89SAndroid Build Coastguard Worker 
496*de1e4e89SAndroid Build Coastguard Worker 	if (tb[IFLA_BOND_PRIMARY_RESELECT]) {
497*de1e4e89SAndroid Build Coastguard Worker 		const char *primary_reselect = get_name(primary_reselect_tbl,
498*de1e4e89SAndroid Build Coastguard Worker 							rta_getattr_u8(tb[IFLA_BOND_PRIMARY_RESELECT]));
499*de1e4e89SAndroid Build Coastguard Worker 		print_string(PRINT_ANY,
500*de1e4e89SAndroid Build Coastguard Worker 			     "primary_reselect",
501*de1e4e89SAndroid Build Coastguard Worker 			     "primary_reselect %s ",
502*de1e4e89SAndroid Build Coastguard Worker 			     primary_reselect);
503*de1e4e89SAndroid Build Coastguard Worker 	}
504*de1e4e89SAndroid Build Coastguard Worker 
505*de1e4e89SAndroid Build Coastguard Worker 	if (tb[IFLA_BOND_FAIL_OVER_MAC]) {
506*de1e4e89SAndroid Build Coastguard Worker 		const char *fail_over_mac = get_name(fail_over_mac_tbl,
507*de1e4e89SAndroid Build Coastguard Worker 						     rta_getattr_u8(tb[IFLA_BOND_FAIL_OVER_MAC]));
508*de1e4e89SAndroid Build Coastguard Worker 		print_string(PRINT_ANY,
509*de1e4e89SAndroid Build Coastguard Worker 			     "fail_over_mac",
510*de1e4e89SAndroid Build Coastguard Worker 			     "fail_over_mac %s ",
511*de1e4e89SAndroid Build Coastguard Worker 			     fail_over_mac);
512*de1e4e89SAndroid Build Coastguard Worker 	}
513*de1e4e89SAndroid Build Coastguard Worker 
514*de1e4e89SAndroid Build Coastguard Worker 	if (tb[IFLA_BOND_XMIT_HASH_POLICY]) {
515*de1e4e89SAndroid Build Coastguard Worker 		const char *xmit_hash_policy = get_name(xmit_hash_policy_tbl,
516*de1e4e89SAndroid Build Coastguard Worker 							rta_getattr_u8(tb[IFLA_BOND_XMIT_HASH_POLICY]));
517*de1e4e89SAndroid Build Coastguard Worker 		print_string(PRINT_ANY,
518*de1e4e89SAndroid Build Coastguard Worker 			     "xmit_hash_policy",
519*de1e4e89SAndroid Build Coastguard Worker 			     "xmit_hash_policy %s ",
520*de1e4e89SAndroid Build Coastguard Worker 			     xmit_hash_policy);
521*de1e4e89SAndroid Build Coastguard Worker 	}
522*de1e4e89SAndroid Build Coastguard Worker 
523*de1e4e89SAndroid Build Coastguard Worker 	if (tb[IFLA_BOND_RESEND_IGMP])
524*de1e4e89SAndroid Build Coastguard Worker 		print_uint(PRINT_ANY,
525*de1e4e89SAndroid Build Coastguard Worker 			   "resend_igmp",
526*de1e4e89SAndroid Build Coastguard Worker 			   "resend_igmp %u ",
527*de1e4e89SAndroid Build Coastguard Worker 			   rta_getattr_u32(tb[IFLA_BOND_RESEND_IGMP]));
528*de1e4e89SAndroid Build Coastguard Worker 
529*de1e4e89SAndroid Build Coastguard Worker 	if (tb[IFLA_BOND_NUM_PEER_NOTIF])
530*de1e4e89SAndroid Build Coastguard Worker 		print_uint(PRINT_ANY,
531*de1e4e89SAndroid Build Coastguard Worker 			   "num_peer_notif",
532*de1e4e89SAndroid Build Coastguard Worker 			   "num_grat_arp %u ",
533*de1e4e89SAndroid Build Coastguard Worker 			   rta_getattr_u8(tb[IFLA_BOND_NUM_PEER_NOTIF]));
534*de1e4e89SAndroid Build Coastguard Worker 
535*de1e4e89SAndroid Build Coastguard Worker 	if (tb[IFLA_BOND_ALL_SLAVES_ACTIVE])
536*de1e4e89SAndroid Build Coastguard Worker 		print_uint(PRINT_ANY,
537*de1e4e89SAndroid Build Coastguard Worker 			   "all_slaves_active",
538*de1e4e89SAndroid Build Coastguard Worker 			   "all_slaves_active %u ",
539*de1e4e89SAndroid Build Coastguard Worker 			   rta_getattr_u8(tb[IFLA_BOND_ALL_SLAVES_ACTIVE]));
540*de1e4e89SAndroid Build Coastguard Worker 
541*de1e4e89SAndroid Build Coastguard Worker 	if (tb[IFLA_BOND_MIN_LINKS])
542*de1e4e89SAndroid Build Coastguard Worker 		print_uint(PRINT_ANY,
543*de1e4e89SAndroid Build Coastguard Worker 			   "min_links",
544*de1e4e89SAndroid Build Coastguard Worker 			   "min_links %u ",
545*de1e4e89SAndroid Build Coastguard Worker 			   rta_getattr_u32(tb[IFLA_BOND_MIN_LINKS]));
546*de1e4e89SAndroid Build Coastguard Worker 
547*de1e4e89SAndroid Build Coastguard Worker 	if (tb[IFLA_BOND_LP_INTERVAL])
548*de1e4e89SAndroid Build Coastguard Worker 		print_uint(PRINT_ANY,
549*de1e4e89SAndroid Build Coastguard Worker 			   "lp_interval",
550*de1e4e89SAndroid Build Coastguard Worker 			   "lp_interval %u ",
551*de1e4e89SAndroid Build Coastguard Worker 			   rta_getattr_u32(tb[IFLA_BOND_LP_INTERVAL]));
552*de1e4e89SAndroid Build Coastguard Worker 
553*de1e4e89SAndroid Build Coastguard Worker 	if (tb[IFLA_BOND_PACKETS_PER_SLAVE])
554*de1e4e89SAndroid Build Coastguard Worker 		print_uint(PRINT_ANY,
555*de1e4e89SAndroid Build Coastguard Worker 			   "packets_per_slave",
556*de1e4e89SAndroid Build Coastguard Worker 			   "packets_per_slave %u ",
557*de1e4e89SAndroid Build Coastguard Worker 			   rta_getattr_u32(tb[IFLA_BOND_PACKETS_PER_SLAVE]));
558*de1e4e89SAndroid Build Coastguard Worker 
559*de1e4e89SAndroid Build Coastguard Worker 	if (tb[IFLA_BOND_AD_LACP_RATE]) {
560*de1e4e89SAndroid Build Coastguard Worker 		const char *lacp_rate = get_name(lacp_rate_tbl,
561*de1e4e89SAndroid Build Coastguard Worker 						 rta_getattr_u8(tb[IFLA_BOND_AD_LACP_RATE]));
562*de1e4e89SAndroid Build Coastguard Worker 		print_string(PRINT_ANY,
563*de1e4e89SAndroid Build Coastguard Worker 			     "ad_lacp_rate",
564*de1e4e89SAndroid Build Coastguard Worker 			     "lacp_rate %s ",
565*de1e4e89SAndroid Build Coastguard Worker 			     lacp_rate);
566*de1e4e89SAndroid Build Coastguard Worker 	}
567*de1e4e89SAndroid Build Coastguard Worker 
568*de1e4e89SAndroid Build Coastguard Worker 	if (tb[IFLA_BOND_AD_SELECT]) {
569*de1e4e89SAndroid Build Coastguard Worker 		const char *ad_select = get_name(ad_select_tbl,
570*de1e4e89SAndroid Build Coastguard Worker 						 rta_getattr_u8(tb[IFLA_BOND_AD_SELECT]));
571*de1e4e89SAndroid Build Coastguard Worker 		print_string(PRINT_ANY,
572*de1e4e89SAndroid Build Coastguard Worker 			     "ad_select",
573*de1e4e89SAndroid Build Coastguard Worker 			     "ad_select %s ",
574*de1e4e89SAndroid Build Coastguard Worker 			     ad_select);
575*de1e4e89SAndroid Build Coastguard Worker 	}
576*de1e4e89SAndroid Build Coastguard Worker 
577*de1e4e89SAndroid Build Coastguard Worker 	if (tb[IFLA_BOND_AD_INFO]) {
578*de1e4e89SAndroid Build Coastguard Worker 		struct rtattr *adtb[IFLA_BOND_AD_INFO_MAX + 1];
579*de1e4e89SAndroid Build Coastguard Worker 
580*de1e4e89SAndroid Build Coastguard Worker 		parse_rtattr_nested(adtb, IFLA_BOND_AD_INFO_MAX,
581*de1e4e89SAndroid Build Coastguard Worker 				    tb[IFLA_BOND_AD_INFO]);
582*de1e4e89SAndroid Build Coastguard Worker 
583*de1e4e89SAndroid Build Coastguard Worker 		open_json_object("ad_info");
584*de1e4e89SAndroid Build Coastguard Worker 
585*de1e4e89SAndroid Build Coastguard Worker 		if (adtb[IFLA_BOND_AD_INFO_AGGREGATOR])
586*de1e4e89SAndroid Build Coastguard Worker 			print_int(PRINT_ANY,
587*de1e4e89SAndroid Build Coastguard Worker 				  "aggregator",
588*de1e4e89SAndroid Build Coastguard Worker 				  "ad_aggregator %d ",
589*de1e4e89SAndroid Build Coastguard Worker 				  rta_getattr_u16(adtb[IFLA_BOND_AD_INFO_AGGREGATOR]));
590*de1e4e89SAndroid Build Coastguard Worker 
591*de1e4e89SAndroid Build Coastguard Worker 		if (adtb[IFLA_BOND_AD_INFO_NUM_PORTS])
592*de1e4e89SAndroid Build Coastguard Worker 			print_int(PRINT_ANY,
593*de1e4e89SAndroid Build Coastguard Worker 				  "num_ports",
594*de1e4e89SAndroid Build Coastguard Worker 				  "ad_num_ports %d ",
595*de1e4e89SAndroid Build Coastguard Worker 				  rta_getattr_u16(adtb[IFLA_BOND_AD_INFO_NUM_PORTS]));
596*de1e4e89SAndroid Build Coastguard Worker 
597*de1e4e89SAndroid Build Coastguard Worker 		if (adtb[IFLA_BOND_AD_INFO_ACTOR_KEY])
598*de1e4e89SAndroid Build Coastguard Worker 			print_int(PRINT_ANY,
599*de1e4e89SAndroid Build Coastguard Worker 				  "actor_key",
600*de1e4e89SAndroid Build Coastguard Worker 				  "ad_actor_key %d ",
601*de1e4e89SAndroid Build Coastguard Worker 				  rta_getattr_u16(adtb[IFLA_BOND_AD_INFO_ACTOR_KEY]));
602*de1e4e89SAndroid Build Coastguard Worker 
603*de1e4e89SAndroid Build Coastguard Worker 		if (adtb[IFLA_BOND_AD_INFO_PARTNER_KEY])
604*de1e4e89SAndroid Build Coastguard Worker 			print_int(PRINT_ANY,
605*de1e4e89SAndroid Build Coastguard Worker 				  "partner_key",
606*de1e4e89SAndroid Build Coastguard Worker 				  "ad_partner_key %d ",
607*de1e4e89SAndroid Build Coastguard Worker 				  rta_getattr_u16(adtb[IFLA_BOND_AD_INFO_PARTNER_KEY]));
608*de1e4e89SAndroid Build Coastguard Worker 
609*de1e4e89SAndroid Build Coastguard Worker 		if (adtb[IFLA_BOND_AD_INFO_PARTNER_MAC]) {
610*de1e4e89SAndroid Build Coastguard Worker 			unsigned char *p =
611*de1e4e89SAndroid Build Coastguard Worker 				RTA_DATA(adtb[IFLA_BOND_AD_INFO_PARTNER_MAC]);
612*de1e4e89SAndroid Build Coastguard Worker 			SPRINT_BUF(b);
613*de1e4e89SAndroid Build Coastguard Worker 			print_string(PRINT_ANY,
614*de1e4e89SAndroid Build Coastguard Worker 				     "partner_mac",
615*de1e4e89SAndroid Build Coastguard Worker 				     "ad_partner_mac %s ",
616*de1e4e89SAndroid Build Coastguard Worker 				     ll_addr_n2a(p, ETH_ALEN, 0, b, sizeof(b)));
617*de1e4e89SAndroid Build Coastguard Worker 		}
618*de1e4e89SAndroid Build Coastguard Worker 
619*de1e4e89SAndroid Build Coastguard Worker 		close_json_object();
620*de1e4e89SAndroid Build Coastguard Worker 	}
621*de1e4e89SAndroid Build Coastguard Worker 
622*de1e4e89SAndroid Build Coastguard Worker 	if (tb[IFLA_BOND_AD_ACTOR_SYS_PRIO]) {
623*de1e4e89SAndroid Build Coastguard Worker 		print_uint(PRINT_ANY,
624*de1e4e89SAndroid Build Coastguard Worker 			   "ad_actor_sys_prio",
625*de1e4e89SAndroid Build Coastguard Worker 			   "ad_actor_sys_prio %u ",
626*de1e4e89SAndroid Build Coastguard Worker 			   rta_getattr_u16(tb[IFLA_BOND_AD_ACTOR_SYS_PRIO]));
627*de1e4e89SAndroid Build Coastguard Worker 	}
628*de1e4e89SAndroid Build Coastguard Worker 
629*de1e4e89SAndroid Build Coastguard Worker 	if (tb[IFLA_BOND_AD_USER_PORT_KEY]) {
630*de1e4e89SAndroid Build Coastguard Worker 		print_uint(PRINT_ANY,
631*de1e4e89SAndroid Build Coastguard Worker 			   "ad_user_port_key",
632*de1e4e89SAndroid Build Coastguard Worker 			   "ad_user_port_key %u ",
633*de1e4e89SAndroid Build Coastguard Worker 			   rta_getattr_u16(tb[IFLA_BOND_AD_USER_PORT_KEY]));
634*de1e4e89SAndroid Build Coastguard Worker 	}
635*de1e4e89SAndroid Build Coastguard Worker 
636*de1e4e89SAndroid Build Coastguard Worker 	if (tb[IFLA_BOND_AD_ACTOR_SYSTEM]) {
637*de1e4e89SAndroid Build Coastguard Worker 		/* We assume the l2 address is an Ethernet MAC address */
638*de1e4e89SAndroid Build Coastguard Worker 		SPRINT_BUF(b1);
639*de1e4e89SAndroid Build Coastguard Worker 
640*de1e4e89SAndroid Build Coastguard Worker 		print_string(PRINT_ANY,
641*de1e4e89SAndroid Build Coastguard Worker 			     "ad_actor_system",
642*de1e4e89SAndroid Build Coastguard Worker 			     "ad_actor_system %s ",
643*de1e4e89SAndroid Build Coastguard Worker 			     ll_addr_n2a(RTA_DATA(tb[IFLA_BOND_AD_ACTOR_SYSTEM]),
644*de1e4e89SAndroid Build Coastguard Worker 					 RTA_PAYLOAD(tb[IFLA_BOND_AD_ACTOR_SYSTEM]),
645*de1e4e89SAndroid Build Coastguard Worker 					 1 /*ARPHDR_ETHER*/, b1, sizeof(b1)));
646*de1e4e89SAndroid Build Coastguard Worker 	}
647*de1e4e89SAndroid Build Coastguard Worker 
648*de1e4e89SAndroid Build Coastguard Worker 	if (tb[IFLA_BOND_TLB_DYNAMIC_LB]) {
649*de1e4e89SAndroid Build Coastguard Worker 		print_uint(PRINT_ANY,
650*de1e4e89SAndroid Build Coastguard Worker 			   "tlb_dynamic_lb",
651*de1e4e89SAndroid Build Coastguard Worker 			   "tlb_dynamic_lb %u ",
652*de1e4e89SAndroid Build Coastguard Worker 			   rta_getattr_u8(tb[IFLA_BOND_TLB_DYNAMIC_LB]));
653*de1e4e89SAndroid Build Coastguard Worker 	}
654*de1e4e89SAndroid Build Coastguard Worker }
655*de1e4e89SAndroid Build Coastguard Worker 
bond_print_help(struct link_util * lu,int argc,char ** argv,FILE * f)656*de1e4e89SAndroid Build Coastguard Worker static void bond_print_help(struct link_util *lu, int argc, char **argv,
657*de1e4e89SAndroid Build Coastguard Worker 			    FILE *f)
658*de1e4e89SAndroid Build Coastguard Worker {
659*de1e4e89SAndroid Build Coastguard Worker 	print_explain(f);
660*de1e4e89SAndroid Build Coastguard Worker }
661*de1e4e89SAndroid Build Coastguard Worker 
662*de1e4e89SAndroid Build Coastguard Worker struct link_util bond_link_util = {
663*de1e4e89SAndroid Build Coastguard Worker 	.id		= "bond",
664*de1e4e89SAndroid Build Coastguard Worker 	.maxattr	= IFLA_BOND_MAX,
665*de1e4e89SAndroid Build Coastguard Worker 	.parse_opt	= bond_parse_opt,
666*de1e4e89SAndroid Build Coastguard Worker 	.print_opt	= bond_print_opt,
667*de1e4e89SAndroid Build Coastguard Worker 	.print_help	= bond_print_help,
668*de1e4e89SAndroid Build Coastguard Worker };
669