summaryrefslogtreecommitdiffstats
path: root/ip
diff options
context:
space:
mode:
Diffstat (limited to 'ip')
-rw-r--r--ip/ip.c10
-rw-r--r--ip/ipila.c4
-rw-r--r--ip/ipioam6.c78
-rw-r--r--ip/iplink.c2
-rw-r--r--ip/iplink_bond.c18
-rw-r--r--ip/iproute.c6
-rw-r--r--ip/iproute_lwtunnel.c7
-rw-r--r--ip/rtmon.c4
8 files changed, 111 insertions, 18 deletions
diff --git a/ip/ip.c b/ip/ip.c
index e51fa20..eb49213 100644
--- a/ip/ip.c
+++ b/ip/ip.c
@@ -203,15 +203,15 @@ int main(int argc, char **argv)
argc--;
argv++;
if (argc <= 1)
- usage();
+ missarg("loop count");
max_flush_loops = atoi(argv[1]);
} else if (matches(opt, "-family") == 0) {
argc--;
argv++;
if (argc <= 1)
- usage();
+ missarg("family type");
if (strcmp(argv[1], "help") == 0)
- usage();
+ do_help(argc, argv);
else
preferred_family = read_family(argv[1]);
if (preferred_family == AF_UNSPEC)
@@ -258,7 +258,7 @@ int main(int argc, char **argv)
argc--;
argv++;
if (argc <= 1)
- usage();
+ missarg("batch file");
batch_file = argv[1];
} else if (matches(opt, "-brief") == 0) {
++brief;
@@ -272,7 +272,7 @@ int main(int argc, char **argv)
argc--;
argv++;
if (argc <= 1)
- usage();
+ missarg("rcvbuf size");
if (get_unsigned(&size, argv[1], 0)) {
fprintf(stderr, "Invalid rcvbuf size '%s'\n",
argv[1]);
diff --git a/ip/ipila.c b/ip/ipila.c
index f4387e0..80f34f2 100644
--- a/ip/ipila.c
+++ b/ip/ipila.c
@@ -301,7 +301,9 @@ int do_ipila(int argc, char **argv)
return do_add(argc-1, argv+1);
if (matches(*argv, "delete") == 0)
return do_del(argc-1, argv+1);
- if (matches(*argv, "list") == 0)
+ if (matches(*argv, "show") == 0 ||
+ matches(*argv, "lst") == 0 ||
+ matches(*argv, "list") == 0)
return do_list(argc-1, argv+1);
fprintf(stderr, "Command \"%s\" is unknown, try \"ip ila help\".\n",
diff --git a/ip/ipioam6.c b/ip/ipioam6.c
index b63d7d5..1886098 100644
--- a/ip/ipioam6.c
+++ b/ip/ipioam6.c
@@ -13,6 +13,7 @@
#include <inttypes.h>
#include <linux/genetlink.h>
+#include <linux/ioam6.h>
#include <linux/ioam6_genl.h>
#include "utils.h"
@@ -30,7 +31,8 @@ static void usage(void)
" ip ioam schema show\n"
" ip ioam schema add ID DATA\n"
" ip ioam schema del ID\n"
- " ip ioam namespace set ID schema { ID | none }\n");
+ " ip ioam namespace set ID schema { ID | none }\n"
+ " ip ioam monitor\n");
exit(-1);
}
@@ -42,6 +44,7 @@ static int genl_family = -1;
IOAM6_GENL_VERSION, _cmd, _flags)
static struct {
+ bool monitor;
unsigned int cmd;
__u32 sc_id;
__u32 ns_data;
@@ -96,6 +99,37 @@ static void print_schema(struct rtattr *attrs[])
print_nl();
}
+static void print_trace(struct rtattr *attrs[])
+{
+ __u8 data[IOAM6_TRACE_DATA_SIZE_MAX];
+ int len, i = 0;
+
+ printf("[TRACE] ");
+
+ if (attrs[IOAM6_EVENT_ATTR_TRACE_NAMESPACE])
+ printf("Namespace=%u ",
+ rta_getattr_u16(attrs[IOAM6_EVENT_ATTR_TRACE_NAMESPACE]));
+
+ if (attrs[IOAM6_EVENT_ATTR_TRACE_NODELEN])
+ printf("NodeLen=%u ",
+ rta_getattr_u8(attrs[IOAM6_EVENT_ATTR_TRACE_NODELEN]));
+
+ if (attrs[IOAM6_EVENT_ATTR_TRACE_TYPE])
+ printf("Type=%#08x ",
+ rta_getattr_u32(attrs[IOAM6_EVENT_ATTR_TRACE_TYPE]));
+
+ len = RTA_PAYLOAD(attrs[IOAM6_EVENT_ATTR_TRACE_DATA]);
+ memcpy(data, RTA_DATA(attrs[IOAM6_EVENT_ATTR_TRACE_DATA]), len);
+
+ printf("Data=");
+ while (i < len) {
+ printf("%02x", data[i]);
+ i++;
+ }
+
+ printf("\n");
+}
+
static int process_msg(struct nlmsghdr *n, void *arg)
{
struct rtattr *attrs[IOAM6_ATTR_MAX + 1];
@@ -126,6 +160,32 @@ static int process_msg(struct nlmsghdr *n, void *arg)
return 0;
}
+static int ioam6_monitor_msg(struct rtnl_ctrl_data *ctrl, struct nlmsghdr *n,
+ void *arg)
+{
+ struct rtattr *attrs[IOAM6_EVENT_ATTR_MAX + 1];
+ const struct genlmsghdr *ghdr = NLMSG_DATA(n);
+ int len = n->nlmsg_len;
+
+ if (n->nlmsg_type != genl_family)
+ return -1;
+
+ len -= NLMSG_LENGTH(GENL_HDRLEN);
+ if (len < 0)
+ return -1;
+
+ parse_rtattr(attrs, IOAM6_EVENT_ATTR_MAX,
+ (void *)ghdr + GENL_HDRLEN, len);
+
+ switch (ghdr->cmd) {
+ case IOAM6_EVENT_TRACE:
+ print_trace(attrs);
+ break;
+ }
+
+ return 0;
+}
+
static int ioam6_do_cmd(void)
{
IOAM6_REQUEST(req, 1056, opts.cmd, NLM_F_REQUEST);
@@ -134,6 +194,19 @@ static int ioam6_do_cmd(void)
if (genl_init_handle(&grth, IOAM6_GENL_NAME, &genl_family))
exit(1);
+ if (opts.monitor) {
+ if (genl_add_mcast_grp(&grth, genl_family,
+ IOAM6_GENL_EV_GRP_NAME) < 0) {
+ perror("can't subscribe to ioam6 events");
+ exit(1);
+ }
+
+ if (rtnl_listen(&grth, ioam6_monitor_msg, stdout) < 0)
+ exit(1);
+
+ return 0;
+ }
+
req.n.nlmsg_type = genl_family;
switch (opts.cmd) {
@@ -325,6 +398,9 @@ int do_ioam6(int argc, char **argv)
invarg("Unknown", *argv);
}
+ } else if (strcmp(*argv, "monitor") == 0) {
+ opts.monitor = true;
+
} else {
invarg("Unknown", *argv);
}
diff --git a/ip/iplink.c b/ip/iplink.c
index 95314af..d5cb9a0 100644
--- a/ip/iplink.c
+++ b/ip/iplink.c
@@ -64,7 +64,7 @@ void iplink_usage(void)
"\n"
" ip link delete { DEVICE | dev DEVICE | group DEVGROUP } type TYPE [ ARGS ]\n"
"\n"
- " ip link set { DEVICE | dev DEVICE | group DEVGROUP }\n"
+ " ip link { set | change } { DEVICE | dev DEVICE | group DEVGROUP }\n"
" [ { up | down } ]\n"
" [ type TYPE ARGS ]\n");
diff --git a/ip/iplink_bond.c b/ip/iplink_bond.c
index 214244d..19af67d 100644
--- a/ip/iplink_bond.c
+++ b/ip/iplink_bond.c
@@ -148,6 +148,7 @@ static void print_explain(FILE *f)
" [ tlb_dynamic_lb TLB_DYNAMIC_LB ]\n"
" [ lacp_rate LACP_RATE ]\n"
" [ lacp_active LACP_ACTIVE]\n"
+ " [ coupled_control COUPLED_CONTROL ]\n"
" [ ad_select AD_SELECT ]\n"
" [ ad_user_port_key PORTKEY ]\n"
" [ ad_actor_sys_prio SYSPRIO ]\n"
@@ -163,6 +164,7 @@ static void print_explain(FILE *f)
"LACP_ACTIVE := off|on\n"
"LACP_RATE := slow|fast\n"
"AD_SELECT := stable|bandwidth|count\n"
+ "COUPLED_CONTROL := off|on\n"
);
}
@@ -176,13 +178,14 @@ static int bond_parse_opt(struct link_util *lu, int argc, char **argv,
{
__u8 mode, use_carrier, primary_reselect, fail_over_mac;
__u8 xmit_hash_policy, num_peer_notif, all_slaves_active;
- __u8 lacp_active, lacp_rate, ad_select, tlb_dynamic_lb;
+ __u8 lacp_active, lacp_rate, ad_select, tlb_dynamic_lb, coupled_control;
__u16 ad_user_port_key, ad_actor_sys_prio;
__u32 miimon, updelay, downdelay, peer_notify_delay, arp_interval, arp_validate;
__u32 arp_all_targets, resend_igmp, min_links, lp_interval;
__u32 packets_per_slave;
__u8 missed_max;
unsigned int ifindex;
+ int ret;
while (argc > 0) {
if (matches(*argv, "mode") == 0) {
@@ -367,6 +370,12 @@ static int bond_parse_opt(struct link_util *lu, int argc, char **argv,
lacp_active = get_index(lacp_active_tbl, *argv);
addattr8(n, 1024, IFLA_BOND_AD_LACP_ACTIVE, lacp_active);
+ } else if (strcmp(*argv, "coupled_control") == 0) {
+ NEXT_ARG();
+ coupled_control = parse_on_off("coupled_control", *argv, &ret);
+ if (ret)
+ return ret;
+ addattr8(n, 1024, IFLA_BOND_COUPLED_CONTROL, coupled_control);
} else if (matches(*argv, "ad_select") == 0) {
NEXT_ARG();
if (get_index(ad_select_tbl, *argv) < 0)
@@ -659,6 +668,13 @@ static void bond_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb[])
lacp_rate);
}
+ if (tb[IFLA_BOND_COUPLED_CONTROL]) {
+ print_on_off(PRINT_ANY,
+ "coupled_control",
+ "coupled_control %s ",
+ rta_getattr_u8(tb[IFLA_BOND_COUPLED_CONTROL]));
+ }
+
if (tb[IFLA_BOND_AD_SELECT]) {
const char *ad_select = get_name(ad_select_tbl,
rta_getattr_u8(tb[IFLA_BOND_AD_SELECT]));
diff --git a/ip/iproute.c b/ip/iproute.c
index 73dbab4..b530461 100644
--- a/ip/iproute.c
+++ b/ip/iproute.c
@@ -61,12 +61,13 @@ static void usage(void)
" ip route save SELECTOR\n"
" ip route restore\n"
" ip route showdump\n"
- " ip route get [ ROUTE_GET_FLAGS ] ADDRESS\n"
+ " ip route get [ ROUTE_GET_FLAGS ] [ to ] ADDRESS\n"
" [ from ADDRESS iif STRING ]\n"
" [ oif STRING ] [ tos TOS ]\n"
" [ mark NUMBER ] [ vrf NAME ]\n"
" [ uid NUMBER ] [ ipproto PROTOCOL ]\n"
" [ sport NUMBER ] [ dport NUMBER ]\n"
+ " [ as ADDRESS ]\n"
" ip route { add | del | change | append | replace } ROUTE\n"
"SELECTOR := [ root PREFIX ] [ match PREFIX ] [ exact PREFIX ]\n"
" [ table TABLE_ID ] [ vrf NAME ] [ proto RTPROTO ]\n"
@@ -112,7 +113,8 @@ static void usage(void)
"FLAVOR := { psp | usp | usd | next-csid }\n"
"IOAM6HDR := trace prealloc type IOAM6_TRACE_TYPE ns IOAM6_NAMESPACE size IOAM6_TRACE_SIZE\n"
"XFRMINFO := if_id IF_ID [ link_dev LINK ]\n"
- "ROUTE_GET_FLAGS := [ fibmatch ]\n");
+ "ROUTE_GET_FLAGS := ROUTE_GET_FLAG [ ROUTE_GET_FLAGS ]\n"
+ "ROUTE_GET_FLAG := [ connected | fibmatch | notify ]\n");
exit(-1);
}
diff --git a/ip/iproute_lwtunnel.c b/ip/iproute_lwtunnel.c
index 9498597..b4df434 100644
--- a/ip/iproute_lwtunnel.c
+++ b/ip/iproute_lwtunnel.c
@@ -2228,11 +2228,8 @@ int lwt_parse_encap(struct rtattr *rta, size_t len, int *argcp, char ***argvp,
invarg("\"encap type\" value is invalid\n", *argv);
NEXT_ARG();
- if (argc <= 1) {
- fprintf(stderr,
- "Error: unexpected end of line after \"encap\"\n");
- exit(-1);
- }
+ if (argc <= 1)
+ missarg("encap type");
nest = rta_nest(rta, len, encap_attr);
switch (type) {
diff --git a/ip/rtmon.c b/ip/rtmon.c
index aad9968..08105d6 100644
--- a/ip/rtmon.c
+++ b/ip/rtmon.c
@@ -82,7 +82,7 @@ main(int argc, char **argv)
argc--;
argv++;
if (argc <= 1)
- usage();
+ missarg("family type");
if (strcmp(argv[1], "inet") == 0)
family = AF_INET;
else if (strcmp(argv[1], "inet6") == 0)
@@ -108,7 +108,7 @@ main(int argc, char **argv)
argc--;
argv++;
if (argc <= 1)
- usage();
+ missarg("file");
file = argv[1];
} else if (matches(argv[1], "link") == 0) {
llink = 1;