diff options
author | Hangbin Liu <liuhangbin@gmail.com> | 2022-02-21 13:54:58 +0800 |
---|---|---|
committer | David Ahern <dsahern@kernel.org> | 2022-02-27 18:31:28 -0700 |
commit | 9831202f2125d2822e725fea61097b17eb994fca (patch) | |
tree | db5270a7c4ec62a327a288201252ae29a7a93c18 | |
parent | 8cc6e4e72516bc2e1c83ee145e7f118c5edb1fdf (diff) | |
download | iproute2-9831202f2125d2822e725fea61097b17eb994fca.tar.gz |
bond: add ns_ip6_target option
Similar with arp_ip_target, this option add bond IPv6 NS/NA monitor
support. When IPv6 target was set, the ARP target will be disabled.
Signed-off-by: Hangbin Liu <liuhangbin@gmail.com>
Signed-off-by: David Ahern <dsahern@kernel.org>
-rw-r--r-- | ip/iplink_bond.c | 53 |
1 files changed, 52 insertions, 1 deletions
diff --git a/ip/iplink_bond.c b/ip/iplink_bond.c index 2bfdf82f2..650411fc7 100644 --- a/ip/iplink_bond.c +++ b/ip/iplink_bond.c @@ -21,6 +21,7 @@ #include "json_print.h" #define BOND_MAX_ARP_TARGETS 16 +#define BOND_MAX_NS_TARGETS BOND_MAX_ARP_TARGETS static unsigned int xstats_print_attr; static int filter_index; @@ -136,6 +137,7 @@ static void print_explain(FILE *f) " [ arp_validate ARP_VALIDATE ]\n" " [ arp_all_targets ARP_ALL_TARGETS ]\n" " [ arp_ip_target [ ARP_IP_TARGET, ... ] ]\n" + " [ ns_ip6_target [ NS_IP6_TARGET, ... ] ]\n" " [ primary SLAVE_DEV ]\n" " [ primary_reselect PRIMARY_RESELECT ]\n" " [ fail_over_mac FAIL_OVER_MAC ]\n" @@ -248,6 +250,25 @@ static int bond_parse_opt(struct link_util *lu, int argc, char **argv, addattr_nest_end(n, nest); } addattr_nest_end(n, nest); + } else if (strcmp(*argv, "ns_ip6_target") == 0) { + struct rtattr *nest = addattr_nest(n, 1024, + IFLA_BOND_NS_IP6_TARGET); + if (NEXT_ARG_OK()) { + NEXT_ARG(); + char *targets = strdupa(*argv); + char *target = strtok(targets, ","); + int i; + + for (i = 0; target && i < BOND_MAX_NS_TARGETS; i++) { + inet_prefix ip6_addr; + + get_addr(&ip6_addr, target, AF_INET6); + addattr_l(n, 1024, i, ip6_addr.data, sizeof(struct in6_addr)); + target = strtok(NULL, ","); + } + addattr_nest_end(n, nest); + } + addattr_nest_end(n, nest); } else if (matches(*argv, "arp_validate") == 0) { NEXT_ARG(); if (get_index(arp_validate_tbl, *argv) < 0) @@ -404,6 +425,8 @@ static int bond_parse_opt(struct link_util *lu, int argc, char **argv, static void bond_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb[]) { + int i; + if (!tb) return; @@ -469,7 +492,6 @@ static void bond_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb[]) if (tb[IFLA_BOND_ARP_IP_TARGET]) { struct rtattr *iptb[BOND_MAX_ARP_TARGETS + 1]; - int i; parse_rtattr_nested(iptb, BOND_MAX_ARP_TARGETS, tb[IFLA_BOND_ARP_IP_TARGET]); @@ -497,6 +519,35 @@ static void bond_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb[]) } } + if (tb[IFLA_BOND_NS_IP6_TARGET]) { + struct rtattr *ip6tb[BOND_MAX_NS_TARGETS + 1]; + + parse_rtattr_nested(ip6tb, BOND_MAX_NS_TARGETS, + tb[IFLA_BOND_NS_IP6_TARGET]); + + if (ip6tb[0]) { + open_json_array(PRINT_JSON, "ns_ip6_target"); + print_string(PRINT_FP, NULL, "ns_ip6_target ", NULL); + } + + for (i = 0; i < BOND_MAX_NS_TARGETS; i++) { + if (ip6tb[i]) + print_string(PRINT_ANY, + NULL, + "%s", + rt_addr_n2a_rta(AF_INET6, ip6tb[i])); + if (!is_json_context() + && i < BOND_MAX_NS_TARGETS-1 + && ip6tb[i+1]) + fprintf(f, ","); + } + + if (ip6tb[0]) { + print_string(PRINT_FP, NULL, " ", NULL); + close_json_array(PRINT_JSON, NULL); + } + } + if (tb[IFLA_BOND_ARP_VALIDATE]) { __u32 arp_v = rta_getattr_u32(tb[IFLA_BOND_ARP_VALIDATE]); const char *arp_validate = get_name(arp_validate_tbl, arp_v); |