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