|
|
049c96 |
From 94fcad34a1305c2851b759b6acb3903c7227580f Mon Sep 17 00:00:00 2001
|
|
|
049c96 |
From: Phil Sutter <psutter@redhat.com>
|
|
|
049c96 |
Date: Tue, 23 Feb 2016 18:24:51 +0100
|
|
|
049c96 |
Subject: [PATCH] iproute2: finish support for bonding attributes
|
|
|
049c96 |
|
|
|
049c96 |
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1269528
|
|
|
049c96 |
Upstream Status: iproute2.git commit 63d127b05dff4
|
|
|
049c96 |
|
|
|
049c96 |
commit 63d127b05dff4d21e8748b2ba9e0e6372897c383
|
|
|
049c96 |
Author: sfeldma@cumulusnetworks.com <sfeldma@cumulusnetworks.com>
|
|
|
049c96 |
Date: Fri Jan 3 18:45:38 2014 -0800
|
|
|
049c96 |
|
|
|
049c96 |
iproute2: finish support for bonding attributes
|
|
|
049c96 |
|
|
|
049c96 |
Add support for bonding attributes just added to net-next.
|
|
|
049c96 |
On set, allow string or number value for enumerated attributes.
|
|
|
049c96 |
On show, use always use string value for attribute.
|
|
|
049c96 |
|
|
|
049c96 |
Signed-off-by: Scott Feldman <sfeldma@cumulusnetworks.com>
|
|
|
049c96 |
---
|
|
|
049c96 |
ip/iplink_bond.c | 458 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-
|
|
|
049c96 |
1 file changed, 451 insertions(+), 7 deletions(-)
|
|
|
049c96 |
|
|
|
049c96 |
diff --git a/ip/iplink_bond.c b/ip/iplink_bond.c
|
|
|
049c96 |
index 3fb7f4f..f0e5ab1 100644
|
|
|
049c96 |
--- a/ip/iplink_bond.c
|
|
|
049c96 |
+++ b/ip/iplink_bond.c
|
|
|
049c96 |
@@ -7,41 +7,165 @@
|
|
|
049c96 |
* 2 of the License, or (at your option) any later version.
|
|
|
049c96 |
*
|
|
|
049c96 |
* Authors: Jiri Pirko <jiri@resnulli.us>
|
|
|
049c96 |
+ * Scott Feldman <sfeldma@cumulusnetworks.com>
|
|
|
049c96 |
*/
|
|
|
049c96 |
|
|
|
049c96 |
#include <stdio.h>
|
|
|
049c96 |
#include <stdlib.h>
|
|
|
049c96 |
#include <string.h>
|
|
|
049c96 |
#include <linux/if_link.h>
|
|
|
049c96 |
+#include <linux/if_ether.h>
|
|
|
049c96 |
#include <net/if.h>
|
|
|
049c96 |
|
|
|
049c96 |
#include "rt_names.h"
|
|
|
049c96 |
#include "utils.h"
|
|
|
049c96 |
#include "ip_common.h"
|
|
|
049c96 |
|
|
|
049c96 |
+#define BOND_MAX_ARP_TARGETS 16
|
|
|
049c96 |
+
|
|
|
049c96 |
+static const char *mode_tbl[] = {
|
|
|
049c96 |
+ "balance-rr",
|
|
|
049c96 |
+ "active-backup",
|
|
|
049c96 |
+ "balance-xor",
|
|
|
049c96 |
+ "broadcast",
|
|
|
049c96 |
+ "802.3ad",
|
|
|
049c96 |
+ "balance-tlb",
|
|
|
049c96 |
+ "balance-alb",
|
|
|
049c96 |
+ NULL,
|
|
|
049c96 |
+};
|
|
|
049c96 |
+
|
|
|
049c96 |
+static const char *arp_validate_tbl[] = {
|
|
|
049c96 |
+ "none",
|
|
|
049c96 |
+ "active",
|
|
|
049c96 |
+ "backup",
|
|
|
049c96 |
+ "all",
|
|
|
049c96 |
+ NULL,
|
|
|
049c96 |
+};
|
|
|
049c96 |
+
|
|
|
049c96 |
+static const char *arp_all_targets_tbl[] = {
|
|
|
049c96 |
+ "any",
|
|
|
049c96 |
+ "all",
|
|
|
049c96 |
+ NULL,
|
|
|
049c96 |
+};
|
|
|
049c96 |
+
|
|
|
049c96 |
+static const char *primary_reselect_tbl[] = {
|
|
|
049c96 |
+ "always",
|
|
|
049c96 |
+ "better",
|
|
|
049c96 |
+ "failure",
|
|
|
049c96 |
+ NULL,
|
|
|
049c96 |
+};
|
|
|
049c96 |
+
|
|
|
049c96 |
+static const char *fail_over_mac_tbl[] = {
|
|
|
049c96 |
+ "none",
|
|
|
049c96 |
+ "active",
|
|
|
049c96 |
+ "follow",
|
|
|
049c96 |
+ NULL,
|
|
|
049c96 |
+};
|
|
|
049c96 |
+
|
|
|
049c96 |
+static const char *xmit_hash_policy_tbl[] = {
|
|
|
049c96 |
+ "layer2",
|
|
|
049c96 |
+ "layer3+4",
|
|
|
049c96 |
+ "layer2+3",
|
|
|
049c96 |
+ "encap2+3",
|
|
|
049c96 |
+ "encap3+4",
|
|
|
049c96 |
+ NULL,
|
|
|
049c96 |
+};
|
|
|
049c96 |
+
|
|
|
049c96 |
+static const char *lacp_rate_tbl[] = {
|
|
|
049c96 |
+ "slow",
|
|
|
049c96 |
+ "fast",
|
|
|
049c96 |
+ NULL,
|
|
|
049c96 |
+};
|
|
|
049c96 |
+
|
|
|
049c96 |
+static const char *ad_select_tbl[] = {
|
|
|
049c96 |
+ "stable",
|
|
|
049c96 |
+ "bandwidth",
|
|
|
049c96 |
+ "count",
|
|
|
049c96 |
+ NULL,
|
|
|
049c96 |
+};
|
|
|
049c96 |
+
|
|
|
049c96 |
+static const char *get_name(const char **tbl, int index)
|
|
|
049c96 |
+{
|
|
|
049c96 |
+ int i;
|
|
|
049c96 |
+
|
|
|
049c96 |
+ for (i = 0; tbl[i]; i++)
|
|
|
049c96 |
+ if (i == index)
|
|
|
049c96 |
+ return tbl[i];
|
|
|
049c96 |
+
|
|
|
049c96 |
+ return "UNKNOWN";
|
|
|
049c96 |
+}
|
|
|
049c96 |
+
|
|
|
049c96 |
+static int get_index(const char **tbl, char *name)
|
|
|
049c96 |
+{
|
|
|
049c96 |
+ int i, index;
|
|
|
049c96 |
+
|
|
|
049c96 |
+ /* check for integer index passed in instead of name */
|
|
|
049c96 |
+ if (get_integer(&index, name, 10) == 0)
|
|
|
049c96 |
+ for (i = 0; tbl[i]; i++)
|
|
|
049c96 |
+ if (i == index)
|
|
|
049c96 |
+ return i;
|
|
|
049c96 |
+
|
|
|
049c96 |
+ for (i = 0; tbl[i]; i++)
|
|
|
049c96 |
+ if (strncmp(tbl[i], name, strlen(tbl[i])) == 0)
|
|
|
049c96 |
+ return i;
|
|
|
049c96 |
+
|
|
|
049c96 |
+ return -1;
|
|
|
049c96 |
+}
|
|
|
049c96 |
+
|
|
|
049c96 |
static void explain(void)
|
|
|
049c96 |
{
|
|
|
049c96 |
fprintf(stderr,
|
|
|
049c96 |
"Usage: ... bond [ mode BONDMODE ] [ active_slave SLAVE_DEV ]\n"
|
|
|
049c96 |
- " [ clear_active_slave ]\n"
|
|
|
049c96 |
+ " [ clear_active_slave ] [ miimon MIIMON ]\n"
|
|
|
049c96 |
+ " [ updelay UPDELAY ] [ downdelay DOWNDELAY ]\n"
|
|
|
049c96 |
+ " [ use_carrier USE_CARRIER ]\n"
|
|
|
049c96 |
+ " [ arp_interval ARP_INTERVAL ]\n"
|
|
|
049c96 |
+ " [ arp_validate ARP_VALIDATE ]\n"
|
|
|
049c96 |
+ " [ arp_all_targets ARP_ALL_TARGETS ]\n"
|
|
|
049c96 |
+ " [ arp_ip_target [ ARP_IP_TARGET, ... ] ]\n"
|
|
|
049c96 |
+ " [ primary SLAVE_DEV ]\n"
|
|
|
049c96 |
+ " [ primary_reselect PRIMARY_RESELECT ]\n"
|
|
|
049c96 |
+ " [ fail_over_mac FAIL_OVER_MAC ]\n"
|
|
|
049c96 |
+ " [ xmit_hash_policy XMIT_HASH_POLICY ]\n"
|
|
|
049c96 |
+ " [ resend_igmp RESEND_IGMP ]\n"
|
|
|
049c96 |
+ " [ num_grat_arp|num_unsol_na NUM_GRAT_ARP|NUM_UNSOL_NA ]\n"
|
|
|
049c96 |
+ " [ all_slaves_active ALL_SLAVES_ACTIVE ]\n"
|
|
|
049c96 |
+ " [ min_links MIN_LINKS ]\n"
|
|
|
049c96 |
+ " [ lp_interval LP_INTERVAL ]\n"
|
|
|
049c96 |
+ " [ packets_per_slave PACKETS_PER_SLAVE ]\n"
|
|
|
049c96 |
+ " [ lacp_rate LACP_RATE ]\n"
|
|
|
049c96 |
+ " [ ad_select AD_SELECT ]\n"
|
|
|
049c96 |
"\n"
|
|
|
049c96 |
- "BONDMODE := 0-6\n"
|
|
|
049c96 |
+ "BONDMODE := balance-rr|active-backup|balance-xor|broadcast|802.3ad|balance-tlb|balance-alb\n"
|
|
|
049c96 |
+ "ARP_VALIDATE := none|active|backup|all\n"
|
|
|
049c96 |
+ "ARP_ALL_TARGETS := any|all\n"
|
|
|
049c96 |
+ "PRIMARY_RESELECT := always|better|failure\n"
|
|
|
049c96 |
+ "FAIL_OVER_MAC := none|active|follow\n"
|
|
|
049c96 |
+ "XMIT_HASH_POLICY := layer2|layer2+3|layer3+4\n"
|
|
|
049c96 |
+ "LACP_RATE := slow|fast\n"
|
|
|
049c96 |
+ "AD_SELECT := stable|bandwidth|count\n"
|
|
|
049c96 |
);
|
|
|
049c96 |
}
|
|
|
049c96 |
|
|
|
049c96 |
static int bond_parse_opt(struct link_util *lu, int argc, char **argv,
|
|
|
049c96 |
struct nlmsghdr *n)
|
|
|
049c96 |
{
|
|
|
049c96 |
- __u8 mode;
|
|
|
049c96 |
+ __u8 mode, use_carrier, primary_reselect, fail_over_mac;
|
|
|
049c96 |
+ __u8 xmit_hash_policy, num_peer_notif, all_slaves_active;
|
|
|
049c96 |
+ __u8 lacp_rate, ad_select;
|
|
|
049c96 |
+ __u32 miimon, updelay, downdelay, arp_interval, arp_validate;
|
|
|
049c96 |
+ __u32 arp_all_targets, resend_igmp, min_links, lp_interval;
|
|
|
049c96 |
+ __u32 packets_per_slave;
|
|
|
049c96 |
unsigned ifindex;
|
|
|
049c96 |
|
|
|
049c96 |
while (argc > 0) {
|
|
|
049c96 |
if (matches(*argv, "mode") == 0) {
|
|
|
049c96 |
NEXT_ARG();
|
|
|
049c96 |
- if (get_u8(&mode, *argv, 0)) {
|
|
|
049c96 |
- invarg("mode %s is invalid", *argv);
|
|
|
049c96 |
+ if (get_index(mode_tbl, *argv) < 0) {
|
|
|
049c96 |
+ invarg("invalid mode", *argv);
|
|
|
049c96 |
return -1;
|
|
|
049c96 |
}
|
|
|
049c96 |
+ mode = get_index(mode_tbl, *argv);
|
|
|
049c96 |
addattr8(n, 1024, IFLA_BOND_MODE, mode);
|
|
|
049c96 |
} else if (matches(*argv, "active_slave") == 0) {
|
|
|
049c96 |
NEXT_ARG();
|
|
|
049c96 |
@@ -51,6 +175,170 @@ static int bond_parse_opt(struct link_util *lu, int argc, char **argv,
|
|
|
049c96 |
addattr32(n, 1024, IFLA_BOND_ACTIVE_SLAVE, ifindex);
|
|
|
049c96 |
} else if (matches(*argv, "clear_active_slave") == 0) {
|
|
|
049c96 |
addattr32(n, 1024, IFLA_BOND_ACTIVE_SLAVE, 0);
|
|
|
049c96 |
+ } else if (matches(*argv, "miimon") == 0) {
|
|
|
049c96 |
+ NEXT_ARG();
|
|
|
049c96 |
+ if (get_u32(&miimon, *argv, 0)) {
|
|
|
049c96 |
+ invarg("invalid miimon", *argv);
|
|
|
049c96 |
+ return -1;
|
|
|
049c96 |
+ }
|
|
|
049c96 |
+ addattr32(n, 1024, IFLA_BOND_MIIMON, miimon);
|
|
|
049c96 |
+ } else if (matches(*argv, "updelay") == 0) {
|
|
|
049c96 |
+ NEXT_ARG();
|
|
|
049c96 |
+ if (get_u32(&updelay, *argv, 0)) {
|
|
|
049c96 |
+ invarg("invalid updelay", *argv);
|
|
|
049c96 |
+ return -1;
|
|
|
049c96 |
+ }
|
|
|
049c96 |
+ addattr32(n, 1024, IFLA_BOND_UPDELAY, updelay);
|
|
|
049c96 |
+ } else if (matches(*argv, "downdelay") == 0) {
|
|
|
049c96 |
+ NEXT_ARG();
|
|
|
049c96 |
+ if (get_u32(&downdelay, *argv, 0)) {
|
|
|
049c96 |
+ invarg("invalid downdelay", *argv);
|
|
|
049c96 |
+ return -1;
|
|
|
049c96 |
+ }
|
|
|
049c96 |
+ addattr32(n, 1024, IFLA_BOND_DOWNDELAY, downdelay);
|
|
|
049c96 |
+ } else if (matches(*argv, "use_carrier") == 0) {
|
|
|
049c96 |
+ NEXT_ARG();
|
|
|
049c96 |
+ if (get_u8(&use_carrier, *argv, 0)) {
|
|
|
049c96 |
+ invarg("invalid use_carrier", *argv);
|
|
|
049c96 |
+ return -1;
|
|
|
049c96 |
+ }
|
|
|
049c96 |
+ addattr8(n, 1024, IFLA_BOND_USE_CARRIER, use_carrier);
|
|
|
049c96 |
+ } else if (matches(*argv, "arp_interval") == 0) {
|
|
|
049c96 |
+ NEXT_ARG();
|
|
|
049c96 |
+ if (get_u32(&arp_interval, *argv, 0)) {
|
|
|
049c96 |
+ invarg("invalid arp_interval", *argv);
|
|
|
049c96 |
+ return -1;
|
|
|
049c96 |
+ }
|
|
|
049c96 |
+ addattr32(n, 1024, IFLA_BOND_ARP_INTERVAL, arp_interval);
|
|
|
049c96 |
+ } else if (matches(*argv, "arp_ip_target") == 0) {
|
|
|
049c96 |
+ struct rtattr * nest = addattr_nest(n, 1024,
|
|
|
049c96 |
+ IFLA_BOND_ARP_IP_TARGET);
|
|
|
049c96 |
+ if (NEXT_ARG_OK()) {
|
|
|
049c96 |
+ NEXT_ARG();
|
|
|
049c96 |
+ char *targets = strdupa(*argv);
|
|
|
049c96 |
+ char *target = strtok(targets, ",");
|
|
|
049c96 |
+ int i;
|
|
|
049c96 |
+
|
|
|
049c96 |
+ for(i = 0; target && i < BOND_MAX_ARP_TARGETS; i++) {
|
|
|
049c96 |
+ __u32 addr = get_addr32(target);
|
|
|
049c96 |
+ addattr32(n, 1024, i, addr);
|
|
|
049c96 |
+ target = strtok(NULL, ",");
|
|
|
049c96 |
+ }
|
|
|
049c96 |
+ addattr_nest_end(n, nest);
|
|
|
049c96 |
+ }
|
|
|
049c96 |
+ addattr_nest_end(n, nest);
|
|
|
049c96 |
+ } else if (matches(*argv, "arp_validate") == 0) {
|
|
|
049c96 |
+ NEXT_ARG();
|
|
|
049c96 |
+ if (get_index(arp_validate_tbl, *argv) < 0) {
|
|
|
049c96 |
+ invarg("invalid arp_validate", *argv);
|
|
|
049c96 |
+ return -1;
|
|
|
049c96 |
+ }
|
|
|
049c96 |
+ arp_validate = get_index(arp_validate_tbl, *argv);
|
|
|
049c96 |
+ addattr32(n, 1024, IFLA_BOND_ARP_VALIDATE, arp_validate);
|
|
|
049c96 |
+ } else if (matches(*argv, "arp_all_targets") == 0) {
|
|
|
049c96 |
+ NEXT_ARG();
|
|
|
049c96 |
+ if (get_index(arp_all_targets_tbl, *argv) < 0) {
|
|
|
049c96 |
+ invarg("invalid arp_all_targets", *argv);
|
|
|
049c96 |
+ return -1;
|
|
|
049c96 |
+ }
|
|
|
049c96 |
+ arp_all_targets = get_index(arp_all_targets_tbl, *argv);
|
|
|
049c96 |
+ addattr32(n, 1024, IFLA_BOND_ARP_ALL_TARGETS, arp_all_targets);
|
|
|
049c96 |
+ } else if (matches(*argv, "primary") == 0) {
|
|
|
049c96 |
+ NEXT_ARG();
|
|
|
049c96 |
+ ifindex = if_nametoindex(*argv);
|
|
|
049c96 |
+ if (!ifindex)
|
|
|
049c96 |
+ return -1;
|
|
|
049c96 |
+ addattr32(n, 1024, IFLA_BOND_PRIMARY, ifindex);
|
|
|
049c96 |
+ } else if (matches(*argv, "primary_reselect") == 0) {
|
|
|
049c96 |
+ NEXT_ARG();
|
|
|
049c96 |
+ if (get_index(primary_reselect_tbl, *argv) < 0) {
|
|
|
049c96 |
+ invarg("invalid primary_reselect", *argv);
|
|
|
049c96 |
+ return -1;
|
|
|
049c96 |
+ }
|
|
|
049c96 |
+ primary_reselect = get_index(primary_reselect_tbl, *argv);
|
|
|
049c96 |
+ addattr8(n, 1024, IFLA_BOND_PRIMARY_RESELECT,
|
|
|
049c96 |
+ primary_reselect);
|
|
|
049c96 |
+ } else if (matches(*argv, "fail_over_mac") == 0) {
|
|
|
049c96 |
+ NEXT_ARG();
|
|
|
049c96 |
+ if (get_index(fail_over_mac_tbl, *argv) < 0) {
|
|
|
049c96 |
+ invarg("invalid fail_over_mac", *argv);
|
|
|
049c96 |
+ return -1;
|
|
|
049c96 |
+ }
|
|
|
049c96 |
+ fail_over_mac = get_index(fail_over_mac_tbl, *argv);
|
|
|
049c96 |
+ addattr8(n, 1024, IFLA_BOND_FAIL_OVER_MAC,
|
|
|
049c96 |
+ fail_over_mac);
|
|
|
049c96 |
+ } else if (matches(*argv, "xmit_hash_policy") == 0) {
|
|
|
049c96 |
+ NEXT_ARG();
|
|
|
049c96 |
+ if (get_index(xmit_hash_policy_tbl, *argv) < 0) {
|
|
|
049c96 |
+ invarg("invalid xmit_hash_policy", *argv);
|
|
|
049c96 |
+ return -1;
|
|
|
049c96 |
+ }
|
|
|
049c96 |
+ xmit_hash_policy = get_index(xmit_hash_policy_tbl, *argv);
|
|
|
049c96 |
+ addattr8(n, 1024, IFLA_BOND_XMIT_HASH_POLICY,
|
|
|
049c96 |
+ xmit_hash_policy);
|
|
|
049c96 |
+ } else if (matches(*argv, "resend_igmp") == 0) {
|
|
|
049c96 |
+ NEXT_ARG();
|
|
|
049c96 |
+ if (get_u32(&resend_igmp, *argv, 0)) {
|
|
|
049c96 |
+ invarg("invalid resend_igmp", *argv);
|
|
|
049c96 |
+ return -1;
|
|
|
049c96 |
+ }
|
|
|
049c96 |
+ addattr32(n, 1024, IFLA_BOND_RESEND_IGMP, resend_igmp);
|
|
|
049c96 |
+ } else if (matches(*argv, "num_grat_arp") == 0 ||
|
|
|
049c96 |
+ matches(*argv, "num_unsol_na") == 0) {
|
|
|
049c96 |
+ NEXT_ARG();
|
|
|
049c96 |
+ if (get_u8(&num_peer_notif, *argv, 0)) {
|
|
|
049c96 |
+ invarg("invalid num_grat_arp|num_unsol_na",
|
|
|
049c96 |
+ *argv);
|
|
|
049c96 |
+ return -1;
|
|
|
049c96 |
+ }
|
|
|
049c96 |
+ addattr8(n, 1024, IFLA_BOND_NUM_PEER_NOTIF,
|
|
|
049c96 |
+ num_peer_notif);
|
|
|
049c96 |
+ } else if (matches(*argv, "all_slaves_active") == 0) {
|
|
|
049c96 |
+ NEXT_ARG();
|
|
|
049c96 |
+ if (get_u8(&all_slaves_active, *argv, 0)) {
|
|
|
049c96 |
+ invarg("invalid all_slaves_active", *argv);
|
|
|
049c96 |
+ return -1;
|
|
|
049c96 |
+ }
|
|
|
049c96 |
+ addattr8(n, 1024, IFLA_BOND_ALL_SLAVES_ACTIVE,
|
|
|
049c96 |
+ all_slaves_active);
|
|
|
049c96 |
+ } else if (matches(*argv, "min_links") == 0) {
|
|
|
049c96 |
+ NEXT_ARG();
|
|
|
049c96 |
+ if (get_u32(&min_links, *argv, 0)) {
|
|
|
049c96 |
+ invarg("invalid min_links", *argv);
|
|
|
049c96 |
+ return -1;
|
|
|
049c96 |
+ }
|
|
|
049c96 |
+ addattr32(n, 1024, IFLA_BOND_MIN_LINKS, min_links);
|
|
|
049c96 |
+ } else if (matches(*argv, "lp_interval") == 0) {
|
|
|
049c96 |
+ NEXT_ARG();
|
|
|
049c96 |
+ if (get_u32(&lp_interval, *argv, 0)) {
|
|
|
049c96 |
+ invarg("invalid lp_interval", *argv);
|
|
|
049c96 |
+ return -1;
|
|
|
049c96 |
+ }
|
|
|
049c96 |
+ addattr32(n, 1024, IFLA_BOND_LP_INTERVAL, lp_interval);
|
|
|
049c96 |
+ } else if (matches(*argv, "packets_per_slave") == 0) {
|
|
|
049c96 |
+ NEXT_ARG();
|
|
|
049c96 |
+ if (get_u32(&packets_per_slave, *argv, 0)) {
|
|
|
049c96 |
+ invarg("invalid packets_per_slave", *argv);
|
|
|
049c96 |
+ return -1;
|
|
|
049c96 |
+ }
|
|
|
049c96 |
+ addattr32(n, 1024, IFLA_BOND_PACKETS_PER_SLAVE,
|
|
|
049c96 |
+ packets_per_slave);
|
|
|
049c96 |
+ } else if (matches(*argv, "lacp_rate") == 0) {
|
|
|
049c96 |
+ NEXT_ARG();
|
|
|
049c96 |
+ if (get_index(lacp_rate_tbl, *argv) < 0) {
|
|
|
049c96 |
+ invarg("invalid lacp_rate", *argv);
|
|
|
049c96 |
+ return -1;
|
|
|
049c96 |
+ }
|
|
|
049c96 |
+ lacp_rate = get_index(lacp_rate_tbl, *argv);
|
|
|
049c96 |
+ addattr8(n, 1024, IFLA_BOND_AD_LACP_RATE, lacp_rate);
|
|
|
049c96 |
+ } else if (matches(*argv, "ad_select") == 0) {
|
|
|
049c96 |
+ NEXT_ARG();
|
|
|
049c96 |
+ if (get_index(ad_select_tbl, *argv) < 0) {
|
|
|
049c96 |
+ invarg("invalid ad_select", *argv);
|
|
|
049c96 |
+ return -1;
|
|
|
049c96 |
+ }
|
|
|
049c96 |
+ ad_select = get_index(ad_select_tbl, *argv);
|
|
|
049c96 |
+ addattr8(n, 1024, IFLA_BOND_AD_SELECT, ad_select);
|
|
|
049c96 |
} else {
|
|
|
049c96 |
fprintf(stderr, "bond: unknown command \"%s\"?\n", *argv);
|
|
|
049c96 |
explain();
|
|
|
049c96 |
@@ -69,8 +357,11 @@ static void bond_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb[])
|
|
|
049c96 |
if (!tb)
|
|
|
049c96 |
return;
|
|
|
049c96 |
|
|
|
049c96 |
- if (tb[IFLA_BOND_MODE])
|
|
|
049c96 |
- fprintf(f, "mode %u ", rta_getattr_u8(tb[IFLA_BOND_MODE]));
|
|
|
049c96 |
+ if (tb[IFLA_BOND_MODE]) {
|
|
|
049c96 |
+ const char *mode = get_name(mode_tbl,
|
|
|
049c96 |
+ rta_getattr_u8(tb[IFLA_BOND_MODE]));
|
|
|
049c96 |
+ fprintf(f, "mode %s ", mode);
|
|
|
049c96 |
+ }
|
|
|
049c96 |
|
|
|
049c96 |
if (tb[IFLA_BOND_ACTIVE_SLAVE] &&
|
|
|
049c96 |
(ifindex = rta_getattr_u32(tb[IFLA_BOND_ACTIVE_SLAVE]))) {
|
|
|
049c96 |
@@ -82,6 +373,159 @@ static void bond_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb[])
|
|
|
049c96 |
else
|
|
|
049c96 |
fprintf(f, "active_slave %u ", ifindex);
|
|
|
049c96 |
}
|
|
|
049c96 |
+
|
|
|
049c96 |
+ if (tb[IFLA_BOND_MIIMON])
|
|
|
049c96 |
+ fprintf(f, "miimon %u ", rta_getattr_u32(tb[IFLA_BOND_MIIMON]));
|
|
|
049c96 |
+
|
|
|
049c96 |
+ if (tb[IFLA_BOND_UPDELAY])
|
|
|
049c96 |
+ fprintf(f, "updelay %u ", rta_getattr_u32(tb[IFLA_BOND_UPDELAY]));
|
|
|
049c96 |
+
|
|
|
049c96 |
+ if (tb[IFLA_BOND_DOWNDELAY])
|
|
|
049c96 |
+ fprintf(f, "downdelay %u ",
|
|
|
049c96 |
+ rta_getattr_u32(tb[IFLA_BOND_DOWNDELAY]));
|
|
|
049c96 |
+
|
|
|
049c96 |
+ if (tb[IFLA_BOND_USE_CARRIER])
|
|
|
049c96 |
+ fprintf(f, "use_carrier %u ",
|
|
|
049c96 |
+ rta_getattr_u8(tb[IFLA_BOND_USE_CARRIER]));
|
|
|
049c96 |
+
|
|
|
049c96 |
+ if (tb[IFLA_BOND_ARP_INTERVAL])
|
|
|
049c96 |
+ fprintf(f, "arp_interval %u ",
|
|
|
049c96 |
+ rta_getattr_u32(tb[IFLA_BOND_ARP_INTERVAL]));
|
|
|
049c96 |
+
|
|
|
049c96 |
+ if (tb[IFLA_BOND_ARP_IP_TARGET]) {
|
|
|
049c96 |
+ struct rtattr *iptb[BOND_MAX_ARP_TARGETS + 1];
|
|
|
049c96 |
+ char buf[INET_ADDRSTRLEN];
|
|
|
049c96 |
+ int i;
|
|
|
049c96 |
+
|
|
|
049c96 |
+ parse_rtattr_nested(iptb, BOND_MAX_ARP_TARGETS,
|
|
|
049c96 |
+ tb[IFLA_BOND_ARP_IP_TARGET]);
|
|
|
049c96 |
+
|
|
|
049c96 |
+ if (iptb[0])
|
|
|
049c96 |
+ fprintf(f, "arp_ip_target ");
|
|
|
049c96 |
+
|
|
|
049c96 |
+ for (i = 0; i < BOND_MAX_ARP_TARGETS; i++) {
|
|
|
049c96 |
+ if (iptb[i])
|
|
|
049c96 |
+ fprintf(f, "%s",
|
|
|
049c96 |
+ rt_addr_n2a(AF_INET,
|
|
|
049c96 |
+ RTA_PAYLOAD(iptb[i]),
|
|
|
049c96 |
+ RTA_DATA(iptb[i]),
|
|
|
049c96 |
+ buf,
|
|
|
049c96 |
+ INET_ADDRSTRLEN));
|
|
|
049c96 |
+ if (i < BOND_MAX_ARP_TARGETS-1 && iptb[i+1])
|
|
|
049c96 |
+ fprintf(f, ",");
|
|
|
049c96 |
+ }
|
|
|
049c96 |
+
|
|
|
049c96 |
+ if (iptb[0])
|
|
|
049c96 |
+ fprintf(f, " ");
|
|
|
049c96 |
+ }
|
|
|
049c96 |
+
|
|
|
049c96 |
+ if (tb[IFLA_BOND_ARP_VALIDATE]) {
|
|
|
049c96 |
+ const char *arp_validate = get_name(arp_validate_tbl,
|
|
|
049c96 |
+ rta_getattr_u32(tb[IFLA_BOND_ARP_VALIDATE]));
|
|
|
049c96 |
+ fprintf(f, "arp_validate %s ", arp_validate);
|
|
|
049c96 |
+ }
|
|
|
049c96 |
+
|
|
|
049c96 |
+ if (tb[IFLA_BOND_ARP_ALL_TARGETS]) {
|
|
|
049c96 |
+ const char *arp_all_targets = get_name(arp_all_targets_tbl,
|
|
|
049c96 |
+ rta_getattr_u32(tb[IFLA_BOND_ARP_ALL_TARGETS]));
|
|
|
049c96 |
+ fprintf(f, "arp_all_target %s ", arp_all_targets);
|
|
|
049c96 |
+ }
|
|
|
049c96 |
+
|
|
|
049c96 |
+ if (tb[IFLA_BOND_PRIMARY] &&
|
|
|
049c96 |
+ (ifindex = rta_getattr_u32(tb[IFLA_BOND_PRIMARY]))) {
|
|
|
049c96 |
+ char buf[IFNAMSIZ];
|
|
|
049c96 |
+ const char *n = if_indextoname(ifindex, buf);
|
|
|
049c96 |
+
|
|
|
049c96 |
+ if (n)
|
|
|
049c96 |
+ fprintf(f, "primary %s ", n);
|
|
|
049c96 |
+ else
|
|
|
049c96 |
+ fprintf(f, "primary %u ", ifindex);
|
|
|
049c96 |
+ }
|
|
|
049c96 |
+
|
|
|
049c96 |
+ if (tb[IFLA_BOND_PRIMARY_RESELECT]) {
|
|
|
049c96 |
+ const char *primary_reselect = get_name(primary_reselect_tbl,
|
|
|
049c96 |
+ rta_getattr_u8(tb[IFLA_BOND_PRIMARY_RESELECT]));
|
|
|
049c96 |
+ fprintf(f, "primary_reselect %s ", primary_reselect);
|
|
|
049c96 |
+ }
|
|
|
049c96 |
+
|
|
|
049c96 |
+ if (tb[IFLA_BOND_FAIL_OVER_MAC]) {
|
|
|
049c96 |
+ const char *fail_over_mac = get_name(fail_over_mac_tbl,
|
|
|
049c96 |
+ rta_getattr_u8(tb[IFLA_BOND_FAIL_OVER_MAC]));
|
|
|
049c96 |
+ fprintf(f, "fail_over_mac %s ", fail_over_mac);
|
|
|
049c96 |
+ }
|
|
|
049c96 |
+
|
|
|
049c96 |
+ if (tb[IFLA_BOND_XMIT_HASH_POLICY]) {
|
|
|
049c96 |
+ const char *xmit_hash_policy = get_name(xmit_hash_policy_tbl,
|
|
|
049c96 |
+ rta_getattr_u8(tb[IFLA_BOND_XMIT_HASH_POLICY]));
|
|
|
049c96 |
+ fprintf(f, "xmit_hash_policy %s ", xmit_hash_policy);
|
|
|
049c96 |
+ }
|
|
|
049c96 |
+
|
|
|
049c96 |
+ if (tb[IFLA_BOND_RESEND_IGMP])
|
|
|
049c96 |
+ fprintf(f, "resend_igmp %u ",
|
|
|
049c96 |
+ rta_getattr_u32(tb[IFLA_BOND_RESEND_IGMP]));
|
|
|
049c96 |
+
|
|
|
049c96 |
+ if (tb[IFLA_BOND_NUM_PEER_NOTIF])
|
|
|
049c96 |
+ fprintf(f, "num_grat_arp %u ",
|
|
|
049c96 |
+ rta_getattr_u8(tb[IFLA_BOND_NUM_PEER_NOTIF]));
|
|
|
049c96 |
+
|
|
|
049c96 |
+ if (tb[IFLA_BOND_ALL_SLAVES_ACTIVE])
|
|
|
049c96 |
+ fprintf(f, "all_slaves_active %u ",
|
|
|
049c96 |
+ rta_getattr_u8(tb[IFLA_BOND_ALL_SLAVES_ACTIVE]));
|
|
|
049c96 |
+
|
|
|
049c96 |
+ if (tb[IFLA_BOND_MIN_LINKS])
|
|
|
049c96 |
+ fprintf(f, "min_links %u ",
|
|
|
049c96 |
+ rta_getattr_u32(tb[IFLA_BOND_MIN_LINKS]));
|
|
|
049c96 |
+
|
|
|
049c96 |
+ if (tb[IFLA_BOND_LP_INTERVAL])
|
|
|
049c96 |
+ fprintf(f, "lp_interval %u ",
|
|
|
049c96 |
+ rta_getattr_u32(tb[IFLA_BOND_LP_INTERVAL]));
|
|
|
049c96 |
+
|
|
|
049c96 |
+ if (tb[IFLA_BOND_PACKETS_PER_SLAVE])
|
|
|
049c96 |
+ fprintf(f, "packets_per_slave %u ",
|
|
|
049c96 |
+ rta_getattr_u32(tb[IFLA_BOND_PACKETS_PER_SLAVE]));
|
|
|
049c96 |
+
|
|
|
049c96 |
+ if (tb[IFLA_BOND_AD_LACP_RATE]) {
|
|
|
049c96 |
+ const char *lacp_rate = get_name(lacp_rate_tbl,
|
|
|
049c96 |
+ rta_getattr_u8(tb[IFLA_BOND_AD_LACP_RATE]));
|
|
|
049c96 |
+ fprintf(f, "lacp_rate %s ", lacp_rate);
|
|
|
049c96 |
+ }
|
|
|
049c96 |
+
|
|
|
049c96 |
+ if (tb[IFLA_BOND_AD_SELECT]) {
|
|
|
049c96 |
+ const char *ad_select = get_name(ad_select_tbl,
|
|
|
049c96 |
+ rta_getattr_u8(tb[IFLA_BOND_AD_SELECT]));
|
|
|
049c96 |
+ fprintf(f, "ad_select %s ", ad_select);
|
|
|
049c96 |
+ }
|
|
|
049c96 |
+
|
|
|
049c96 |
+ if (tb[IFLA_BOND_AD_INFO]) {
|
|
|
049c96 |
+ struct rtattr *adtb[IFLA_BOND_AD_INFO_MAX + 1];
|
|
|
049c96 |
+
|
|
|
049c96 |
+ parse_rtattr_nested(adtb, IFLA_BOND_AD_INFO_MAX,
|
|
|
049c96 |
+ tb[IFLA_BOND_AD_INFO]);
|
|
|
049c96 |
+
|
|
|
049c96 |
+ if (adtb[IFLA_BOND_AD_INFO_AGGREGATOR])
|
|
|
049c96 |
+ fprintf(f, "ad_aggregator %d ",
|
|
|
049c96 |
+ rta_getattr_u16(adtb[IFLA_BOND_AD_INFO_AGGREGATOR]));
|
|
|
049c96 |
+
|
|
|
049c96 |
+ if (adtb[IFLA_BOND_AD_INFO_NUM_PORTS])
|
|
|
049c96 |
+ fprintf(f, "ad_num_ports %d ",
|
|
|
049c96 |
+ rta_getattr_u16(adtb[IFLA_BOND_AD_INFO_NUM_PORTS]));
|
|
|
049c96 |
+
|
|
|
049c96 |
+ if (adtb[IFLA_BOND_AD_INFO_ACTOR_KEY])
|
|
|
049c96 |
+ fprintf(f, "ad_actor_key %d ",
|
|
|
049c96 |
+ rta_getattr_u16(adtb[IFLA_BOND_AD_INFO_ACTOR_KEY]));
|
|
|
049c96 |
+
|
|
|
049c96 |
+ if (adtb[IFLA_BOND_AD_INFO_PARTNER_KEY])
|
|
|
049c96 |
+ fprintf(f, "ad_partner_key %d ",
|
|
|
049c96 |
+ rta_getattr_u16(adtb[IFLA_BOND_AD_INFO_PARTNER_KEY]));
|
|
|
049c96 |
+
|
|
|
049c96 |
+ if (adtb[IFLA_BOND_AD_INFO_PARTNER_MAC]) {
|
|
|
049c96 |
+ unsigned char *p =
|
|
|
049c96 |
+ RTA_DATA(adtb[IFLA_BOND_AD_INFO_PARTNER_MAC]);
|
|
|
049c96 |
+ SPRINT_BUF(b);
|
|
|
049c96 |
+ fprintf(f, "ad_partner_mac %s ",
|
|
|
049c96 |
+ ll_addr_n2a(p, ETH_ALEN, 0, b, sizeof(b)));
|
|
|
049c96 |
+ }
|
|
|
049c96 |
+ }
|
|
|
049c96 |
}
|
|
|
049c96 |
|
|
|
049c96 |
struct link_util bond_link_util = {
|
|
|
049c96 |
--
|
|
|
049c96 |
1.8.3.1
|
|
|
049c96 |
|