aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Ahern <dsahern@gmail.com>2020-01-02 17:49:45 +0000
committerDavid Ahern <dsahern@gmail.com>2020-01-02 17:49:45 +0000
commit404f2de114f24c03677e441d9e5ce589e45a6527 (patch)
treea2d9bc6db5185615d4cf11a27184667fa4911dac
parent39ac2d2b802b42ae460e84cc3fb971ceafb2b4d2 (diff)
parente819d3a03dd19ed3dd0f50bd128f62f972e8240f (diff)
downloadiproute2-404f2de114f24c03677e441d9e5ce589e45a6527.tar.gz
Merge branch 'master' into next
Signed-off-by: David Ahern <dsahern@gmail.com>
-rw-r--r--bridge/vlan.c138
-rw-r--r--devlink/devlink.c153
-rw-r--r--include/json_print.h2
-rw-r--r--ip/link_xfrm.c4
-rw-r--r--lib/utils.c2
-rw-r--r--man/man8/bridge.84
-rw-r--r--man/man8/tc-fq.814
-rw-r--r--man/man8/tc-pie.816
-rw-r--r--tc/q_cbs.c10
-rw-r--r--tc/q_choke.c26
-rw-r--r--tc/q_codel.c45
-rw-r--r--tc/q_fq.c108
-rw-r--r--tc/q_fq_codel.c4
-rw-r--r--tc/q_hhf.c33
-rw-r--r--tc/q_pie.c47
-rw-r--r--tc/q_sfb.c67
-rw-r--r--tc/q_sfq.c66
-rw-r--r--tc/q_tbf.c68
-rw-r--r--testsuite/Makefile3
-rw-r--r--testsuite/lib/generic.sh8
-rwxr-xr-xtestsuite/tests/bridge/vlan/tunnelshow.t33
21 files changed, 546 insertions, 305 deletions
diff --git a/bridge/vlan.c b/bridge/vlan.c
index 6d33b0a99..205851e4f 100644
--- a/bridge/vlan.c
+++ b/bridge/vlan.c
@@ -16,7 +16,11 @@
#include "utils.h"
static unsigned int filter_index, filter_vlan;
-static int show_vlan_tunnel_info = 0;
+
+enum vlan_show_subject {
+ VLAN_SHOW_VLAN,
+ VLAN_SHOW_TUNNELINFO,
+};
static void usage(void)
{
@@ -71,8 +75,8 @@ static int add_tunnel_info(struct nlmsghdr *n, int reqsize,
tinfo = addattr_nest(n, reqsize, IFLA_BRIDGE_VLAN_TUNNEL_INFO);
addattr32(n, reqsize, IFLA_BRIDGE_VLAN_TUNNEL_ID, tun_id);
- addattr32(n, reqsize, IFLA_BRIDGE_VLAN_TUNNEL_VID, vid);
- addattr32(n, reqsize, IFLA_BRIDGE_VLAN_TUNNEL_FLAGS, flags);
+ addattr16(n, reqsize, IFLA_BRIDGE_VLAN_TUNNEL_VID, vid);
+ addattr16(n, reqsize, IFLA_BRIDGE_VLAN_TUNNEL_FLAGS, flags);
addattr_nest_end(n, tinfo);
@@ -252,12 +256,14 @@ static int filter_vlan_check(__u16 vid, __u16 flags)
return 1;
}
-static void open_vlan_port(int ifi_index, const char *fmt)
+static void open_vlan_port(int ifi_index, const char *fmt,
+ enum vlan_show_subject subject)
{
open_json_object(NULL);
print_color_string(PRINT_ANY, COLOR_IFNAME, "ifname", fmt,
ll_index_to_name(ifi_index));
- open_json_array(PRINT_JSON, "vlans");
+ open_json_array(PRINT_JSON,
+ subject == VLAN_SHOW_VLAN ? "vlans": "tunnels");
}
static void close_vlan_port(void)
@@ -266,29 +272,27 @@ static void close_vlan_port(void)
close_json_object();
}
-static void print_range(const char *name, __u16 start, __u16 id)
+static void print_range(const char *name, __u32 start, __u32 id)
{
char end[64];
snprintf(end, sizeof(end), "%sEnd", name);
- print_hu(PRINT_ANY, name, "\t %hu", start);
+ print_uint(PRINT_ANY, name, "\t %u", start);
if (start != id)
- print_hu(PRINT_ANY, end, "-%hu", id);
+ print_uint(PRINT_ANY, end, "-%u", id);
}
-static void print_vlan_tunnel_info(FILE *fp, struct rtattr *tb, int ifindex)
+static void print_vlan_tunnel_info(struct rtattr *tb, int ifindex)
{
struct rtattr *i, *list = tb;
int rem = RTA_PAYLOAD(list);
__u16 last_vid_start = 0;
__u32 last_tunid_start = 0;
- if (!filter_vlan)
- open_vlan_port(ifindex, "%s");
+ open_vlan_port(ifindex, "%s", VLAN_SHOW_TUNNELINFO);
- open_json_array(PRINT_JSON, "tunnel");
for (i = RTA_DATA(list); RTA_OK(i, rem); i = RTA_NEXT(i, rem)) {
struct rtattr *ttb[IFLA_BRIDGE_VLAN_TUNNEL_MAX+1];
__u32 tunnel_id = 0;
@@ -304,7 +308,7 @@ static void print_vlan_tunnel_info(FILE *fp, struct rtattr *tb, int ifindex)
if (ttb[IFLA_BRIDGE_VLAN_TUNNEL_VID])
tunnel_vid =
- rta_getattr_u32(ttb[IFLA_BRIDGE_VLAN_TUNNEL_VID]);
+ rta_getattr_u16(ttb[IFLA_BRIDGE_VLAN_TUNNEL_VID]);
else
continue;
@@ -314,7 +318,7 @@ static void print_vlan_tunnel_info(FILE *fp, struct rtattr *tb, int ifindex)
if (ttb[IFLA_BRIDGE_VLAN_TUNNEL_FLAGS])
tunnel_flags =
- rta_getattr_u32(ttb[IFLA_BRIDGE_VLAN_TUNNEL_FLAGS]);
+ rta_getattr_u16(ttb[IFLA_BRIDGE_VLAN_TUNNEL_FLAGS]);
if (!(tunnel_flags & BRIDGE_VLAN_INFO_RANGE_END)) {
last_vid_start = tunnel_vid;
@@ -327,72 +331,18 @@ static void print_vlan_tunnel_info(FILE *fp, struct rtattr *tb, int ifindex)
else if (vcheck_ret == 0)
continue;
- if (tunnel_flags & BRIDGE_VLAN_INFO_RANGE_BEGIN)
- continue;
-
- if (filter_vlan)
- open_vlan_port(ifindex, "%s");
-
open_json_object(NULL);
print_range("vlan", last_vid_start, tunnel_vid);
print_range("tunid", last_tunid_start, tunnel_id);
close_json_object();
-
print_string(PRINT_FP, NULL, "%s", _SL_);
- if (filter_vlan)
- close_vlan_port();
- }
-
- if (!filter_vlan)
- close_vlan_port();
-}
-
-static int print_vlan_tunnel(struct nlmsghdr *n, void *arg)
-{
- struct ifinfomsg *ifm = NLMSG_DATA(n);
- struct rtattr *tb[IFLA_MAX+1];
- int len = n->nlmsg_len;
- FILE *fp = arg;
-
- if (n->nlmsg_type != RTM_NEWLINK) {
- fprintf(stderr, "Not RTM_NEWLINK: %08x %08x %08x\n",
- n->nlmsg_len, n->nlmsg_type, n->nlmsg_flags);
- return 0;
- }
-
- len -= NLMSG_LENGTH(sizeof(*ifm));
- if (len < 0) {
- fprintf(stderr, "BUG: wrong nlmsg len %d\n", len);
- return -1;
}
-
- if (ifm->ifi_family != AF_BRIDGE)
- return 0;
-
- if (filter_index && filter_index != ifm->ifi_index)
- return 0;
-
- parse_rtattr(tb, IFLA_MAX, IFLA_RTA(ifm), len);
-
- /* if AF_SPEC isn't there, vlan table is not preset for this port */
- if (!tb[IFLA_AF_SPEC]) {
- if (!filter_vlan && !is_json_context()) {
- color_fprintf(fp, COLOR_IFNAME, "%s",
- ll_index_to_name(ifm->ifi_index));
- fprintf(fp, "\tNone\n");
- }
- return 0;
- }
-
- print_vlan_tunnel_info(fp, tb[IFLA_AF_SPEC], ifm->ifi_index);
-
- fflush(fp);
- return 0;
+ close_vlan_port();
}
static int print_vlan(struct nlmsghdr *n, void *arg)
{
- FILE *fp = arg;
+ enum vlan_show_subject *subject = arg;
struct ifinfomsg *ifm = NLMSG_DATA(n);
int len = n->nlmsg_len;
struct rtattr *tb[IFLA_MAX+1];
@@ -420,17 +370,24 @@ static int print_vlan(struct nlmsghdr *n, void *arg)
/* if AF_SPEC isn't there, vlan table is not preset for this port */
if (!tb[IFLA_AF_SPEC]) {
if (!filter_vlan && !is_json_context()) {
- color_fprintf(fp, COLOR_IFNAME, "%s",
+ color_fprintf(stdout, COLOR_IFNAME, "%s",
ll_index_to_name(ifm->ifi_index));
- fprintf(fp, "\tNone\n");
+ fprintf(stdout, "\tNone\n");
}
return 0;
}
- print_vlan_info(tb[IFLA_AF_SPEC], ifm->ifi_index);
+ switch (*subject) {
+ case VLAN_SHOW_VLAN:
+ print_vlan_info(tb[IFLA_AF_SPEC], ifm->ifi_index);
+ break;
+ case VLAN_SHOW_TUNNELINFO:
+ print_vlan_tunnel_info(tb[IFLA_AF_SPEC], ifm->ifi_index);
+ break;
+ }
print_string(PRINT_FP, NULL, "%s", _SL_);
- fflush(fp);
+ fflush(stdout);
return 0;
}
@@ -499,7 +456,7 @@ static void print_vlan_stats_attr(struct rtattr *attr, int ifindex)
/* found vlan stats, first time print the interface name */
if (!found_vlan) {
- open_vlan_port(ifindex, "%-16s");
+ open_vlan_port(ifindex, "%-16s", VLAN_SHOW_VLAN);
found_vlan = true;
} else {
print_string(PRINT_FP, NULL, "%-16s", "");
@@ -543,7 +500,7 @@ static int print_vlan_stats(struct nlmsghdr *n, void *arg)
return 0;
}
-static int vlan_show(int argc, char **argv)
+static int vlan_show(int argc, char **argv, int subject)
{
char *filter_dev = NULL;
int ret = 0;
@@ -576,22 +533,18 @@ static int vlan_show(int argc, char **argv)
(compress_vlans ?
RTEXT_FILTER_BRVLAN_COMPRESSED :
RTEXT_FILTER_BRVLAN)) < 0) {
- perror("Cannont send dump request");
+ perror("Cannot send dump request");
exit(1);
}
if (!is_json_context()) {
- if (show_vlan_tunnel_info)
- printf("port\tvlan ids\ttunnel id\n");
- else
- printf("port\tvlan ids\n");
+ printf("port\tvlan ids");
+ if (subject == VLAN_SHOW_TUNNELINFO)
+ printf("\ttunnel id");
+ printf("\n");
}
- if (show_vlan_tunnel_info)
- ret = rtnl_dump_filter(&rth, print_vlan_tunnel,
- stdout);
- else
- ret = rtnl_dump_filter(&rth, print_vlan, stdout);
+ ret = rtnl_dump_filter(&rth, print_vlan, &subject);
if (ret < 0) {
fprintf(stderr, "Dump ternminated\n");
exit(1);
@@ -601,7 +554,7 @@ static int vlan_show(int argc, char **argv)
filt_mask = IFLA_STATS_FILTER_BIT(IFLA_STATS_LINK_XSTATS);
if (rtnl_statsdump_req_filter(&rth, AF_UNSPEC, filt_mask) < 0) {
- perror("Cannont send dump request");
+ perror("Cannot send dump request");
exit(1);
}
@@ -615,7 +568,7 @@ static int vlan_show(int argc, char **argv)
filt_mask = IFLA_STATS_FILTER_BIT(IFLA_STATS_LINK_XSTATS_SLAVE);
if (rtnl_statsdump_req_filter(&rth, AF_UNSPEC, filt_mask) < 0) {
- perror("Cannont send slave dump request");
+ perror("Cannot send slave dump request");
exit(1);
}
@@ -636,7 +589,7 @@ void print_vlan_info(struct rtattr *tb, int ifindex)
int rem = RTA_PAYLOAD(list);
__u16 last_vid_start = 0;
- open_vlan_port(ifindex, "%s");
+ open_vlan_port(ifindex, "%s", VLAN_SHOW_VLAN);
for (i = RTA_DATA(list); RTA_OK(i, rem); i = RTA_NEXT(i, rem)) {
struct bridge_vlan_info *vinfo;
@@ -677,15 +630,14 @@ int do_vlan(int argc, char **argv)
if (matches(*argv, "show") == 0 ||
matches(*argv, "lst") == 0 ||
matches(*argv, "list") == 0)
- return vlan_show(argc-1, argv+1);
+ return vlan_show(argc-1, argv+1, VLAN_SHOW_VLAN);
if (matches(*argv, "tunnelshow") == 0) {
- show_vlan_tunnel_info = 1;
- return vlan_show(argc-1, argv+1);
+ return vlan_show(argc-1, argv+1, VLAN_SHOW_TUNNELINFO);
}
if (matches(*argv, "help") == 0)
usage();
} else {
- return vlan_show(0, NULL);
+ return vlan_show(0, NULL, VLAN_SHOW_VLAN);
}
fprintf(stderr, "Command \"%s\" is unknown, try \"bridge vlan help\".\n", *argv);
diff --git a/devlink/devlink.c b/devlink/devlink.c
index 0b8985f32..95f05a0b5 100644
--- a/devlink/devlink.c
+++ b/devlink/devlink.c
@@ -6463,12 +6463,23 @@ static int fmsg_value_show(struct dl *dl, int type, struct nlattr *nl_data)
return MNL_CB_OK;
}
+static void pr_out_fmsg_name(struct dl *dl, char **name)
+{
+ if (!*name)
+ return;
+
+ pr_out_name(dl, *name);
+ free(*name);
+ *name = NULL;
+}
+
struct nest_entry {
int attr_type;
struct list_head list;
};
struct fmsg_cb_data {
+ char *name;
struct dl *dl;
uint8_t value_type;
struct list_head entry_list;
@@ -6498,6 +6509,56 @@ static int cmd_fmsg_nest_queue(struct fmsg_cb_data *fmsg_data,
return MNL_CB_OK;
}
+static void pr_out_fmsg_group_start(struct dl *dl, char **name)
+{
+ __pr_out_newline();
+ pr_out_fmsg_name(dl, name);
+ __pr_out_newline();
+ __pr_out_indent_inc();
+}
+
+static void pr_out_fmsg_group_end(struct dl *dl)
+{
+ __pr_out_newline();
+ __pr_out_indent_dec();
+}
+
+static void pr_out_fmsg_start_object(struct dl *dl, char **name)
+{
+ if (dl->json_output) {
+ pr_out_fmsg_name(dl, name);
+ jsonw_start_object(dl->jw);
+ } else {
+ pr_out_fmsg_group_start(dl, name);
+ }
+}
+
+static void pr_out_fmsg_end_object(struct dl *dl)
+{
+ if (dl->json_output)
+ jsonw_end_object(dl->jw);
+ else
+ pr_out_fmsg_group_end(dl);
+}
+
+static void pr_out_fmsg_start_array(struct dl *dl, char **name)
+{
+ if (dl->json_output) {
+ pr_out_fmsg_name(dl, name);
+ jsonw_start_array(dl->jw);
+ } else {
+ pr_out_fmsg_group_start(dl, name);
+ }
+}
+
+static void pr_out_fmsg_end_array(struct dl *dl)
+{
+ if (dl->json_output)
+ jsonw_end_array(dl->jw);
+ else
+ pr_out_fmsg_group_end(dl);
+}
+
static int cmd_fmsg_nest(struct fmsg_cb_data *fmsg_data, uint8_t nest_value,
bool start)
{
@@ -6512,26 +6573,17 @@ static int cmd_fmsg_nest(struct fmsg_cb_data *fmsg_data, uint8_t nest_value,
switch (value) {
case DEVLINK_ATTR_FMSG_OBJ_NEST_START:
if (start)
- pr_out_entry_start(dl);
+ pr_out_fmsg_start_object(dl, &fmsg_data->name);
else
- pr_out_entry_end(dl);
+ pr_out_fmsg_end_object(dl);
break;
case DEVLINK_ATTR_FMSG_PAIR_NEST_START:
break;
case DEVLINK_ATTR_FMSG_ARR_NEST_START:
- if (dl->json_output) {
- if (start)
- jsonw_start_array(dl->jw);
- else
- jsonw_end_array(dl->jw);
- } else {
- if (start) {
- __pr_out_newline();
- __pr_out_indent_inc();
- } else {
- __pr_out_indent_dec();
- }
- }
+ if (start)
+ pr_out_fmsg_start_array(dl, &fmsg_data->name);
+ else
+ pr_out_fmsg_end_array(dl);
break;
default:
return -EINVAL;
@@ -6569,12 +6621,16 @@ static int cmd_fmsg_object_cb(const struct nlmsghdr *nlh, void *data)
return err;
break;
case DEVLINK_ATTR_FMSG_OBJ_NAME:
- pr_out_name(dl, mnl_attr_get_str(nla_object));
+ free(fmsg_data->name);
+ fmsg_data->name = strdup(mnl_attr_get_str(nla_object));
+ if (!fmsg_data->name)
+ return -ENOMEM;
break;
case DEVLINK_ATTR_FMSG_OBJ_VALUE_TYPE:
fmsg_data->value_type = mnl_attr_get_u8(nla_object);
break;
case DEVLINK_ATTR_FMSG_OBJ_VALUE_DATA:
+ pr_out_fmsg_name(dl, &fmsg_data->name);
err = fmsg_value_show(dl, fmsg_data->value_type,
nla_object);
if (err != MNL_CB_OK)
@@ -6587,6 +6643,20 @@ static int cmd_fmsg_object_cb(const struct nlmsghdr *nlh, void *data)
return MNL_CB_OK;
}
+static void cmd_fmsg_init(struct dl *dl, struct fmsg_cb_data *data)
+{
+ /* FMSG is dynamic: opening of an object or array causes a
+ * newline. JSON starts with an { or [, but plain text should
+ * not start with a new line. Ensure this by setting
+ * g_new_line_count to 1: avoiding newline before the first
+ * print.
+ */
+ g_new_line_count = 1;
+ data->name = NULL;
+ data->dl = dl;
+ INIT_LIST_HEAD(&data->entry_list);
+}
+
static int cmd_health_object_common(struct dl *dl, uint8_t cmd, uint16_t flags)
{
struct fmsg_cb_data data;
@@ -6600,9 +6670,9 @@ static int cmd_health_object_common(struct dl *dl, uint8_t cmd, uint16_t flags)
if (err)
return err;
- data.dl = dl;
- INIT_LIST_HEAD(&data.entry_list);
+ cmd_fmsg_init(dl, &data);
err = _mnlg_socket_sndrcv(dl->nlg, nlh, cmd_fmsg_object_cb, &data);
+ free(data.name);
return err;
}
@@ -6654,8 +6724,11 @@ static const char *health_state_name(uint8_t state)
}
}
-static void format_logtime(uint64_t time_ms, char *ts_date, char *ts_time)
+static void pr_out_dump_reporter_format_logtime(struct dl *dl, const struct nlattr *attr)
{
+ char dump_date[HEALTH_REPORTER_TIMESTAMP_FMT_LEN];
+ char dump_time[HEALTH_REPORTER_TIMESTAMP_FMT_LEN];
+ uint64_t time_ms = mnl_attr_get_u64(attr);
struct sysinfo s_info;
struct tm *info;
time_t now, sec;
@@ -6673,16 +6746,35 @@ static void format_logtime(uint64_t time_ms, char *ts_date, char *ts_time)
sec = now - s_info.uptime + time_ms / 1000;
info = localtime(&sec);
out:
- strftime(ts_date, HEALTH_REPORTER_TIMESTAMP_FMT_LEN, "%Y-%m-%d", info);
- strftime(ts_time, HEALTH_REPORTER_TIMESTAMP_FMT_LEN, "%H:%M:%S", info);
+ strftime(dump_date, HEALTH_REPORTER_TIMESTAMP_FMT_LEN, "%Y-%m-%d", info);
+ strftime(dump_time, HEALTH_REPORTER_TIMESTAMP_FMT_LEN, "%H:%M:%S", info);
+ pr_out_str(dl, "last_dump_date", dump_date);
+ pr_out_str(dl, "last_dump_time", dump_time);
+}
+
+static void pr_out_dump_report_timestamp(struct dl *dl, const struct nlattr *attr)
+{
+ char dump_date[HEALTH_REPORTER_TIMESTAMP_FMT_LEN];
+ char dump_time[HEALTH_REPORTER_TIMESTAMP_FMT_LEN];
+ time_t tv_sec;
+ struct tm *tm;
+ uint64_t ts;
+
+ ts = mnl_attr_get_u64(attr);
+ tv_sec = ts / 1000000000;
+ tm = localtime(&tv_sec);
+
+ strftime(dump_date, HEALTH_REPORTER_TIMESTAMP_FMT_LEN, "%Y-%m-%d", tm);
+ strftime(dump_time, HEALTH_REPORTER_TIMESTAMP_FMT_LEN, "%H:%M:%S", tm);
+
+ pr_out_str(dl, "last_dump_date", dump_date);
+ pr_out_str(dl, "last_dump_time", dump_time);
}
static void pr_out_health(struct dl *dl, struct nlattr **tb_health)
{
struct nlattr *tb[DEVLINK_ATTR_MAX + 1] = {};
enum devlink_health_reporter_state state;
- const struct nlattr *attr;
- uint64_t time_ms;
int err;
err = mnl_attr_parse_nested(tb_health[DEVLINK_ATTR_HEALTH_REPORTER],
@@ -6710,17 +6802,10 @@ static void pr_out_health(struct dl *dl, struct nlattr **tb_health)
mnl_attr_get_u64(tb[DEVLINK_ATTR_HEALTH_REPORTER_ERR_COUNT]));
pr_out_u64(dl, "recover",
mnl_attr_get_u64(tb[DEVLINK_ATTR_HEALTH_REPORTER_RECOVER_COUNT]));
- if (tb[DEVLINK_ATTR_HEALTH_REPORTER_DUMP_TS]) {
- char dump_date[HEALTH_REPORTER_TIMESTAMP_FMT_LEN];
- char dump_time[HEALTH_REPORTER_TIMESTAMP_FMT_LEN];
-
- attr = tb[DEVLINK_ATTR_HEALTH_REPORTER_DUMP_TS];
- time_ms = mnl_attr_get_u64(attr);
- format_logtime(time_ms, dump_date, dump_time);
-
- pr_out_str(dl, "last_dump_date", dump_date);
- pr_out_str(dl, "last_dump_time", dump_time);
- }
+ if (tb[DEVLINK_ATTR_HEALTH_REPORTER_DUMP_TS_NS])
+ pr_out_dump_report_timestamp(dl, tb[DEVLINK_ATTR_HEALTH_REPORTER_DUMP_TS_NS]);
+ else if (tb[DEVLINK_ATTR_HEALTH_REPORTER_DUMP_TS])
+ pr_out_dump_reporter_format_logtime(dl, tb[DEVLINK_ATTR_HEALTH_REPORTER_DUMP_TS]);
if (tb[DEVLINK_ATTR_HEALTH_REPORTER_GRACEFUL_PERIOD])
pr_out_u64(dl, "grace_period",
mnl_attr_get_u64(tb[DEVLINK_ATTR_HEALTH_REPORTER_GRACEFUL_PERIOD]));
diff --git a/include/json_print.h b/include/json_print.h
index fe92d14ca..6695654f7 100644
--- a/include/json_print.h
+++ b/include/json_print.h
@@ -34,8 +34,6 @@ void delete_json_obj(void);
bool is_json_context(void);
-void fflush_fp(void);
-
void open_json_object(const char *str);
void close_json_object(void);
void open_json_array(enum output_type type, const char *delim);
diff --git a/ip/link_xfrm.c b/ip/link_xfrm.c
index a28f308d5..7dbfb13f8 100644
--- a/ip/link_xfrm.c
+++ b/ip/link_xfrm.c
@@ -37,7 +37,9 @@ static int xfrm_parse_opt(struct link_util *lu, int argc, char **argv,
exit(nodev(*argv));
} else if (!matches(*argv, "if_id")) {
NEXT_ARG();
- if (!get_u32(&if_id, *argv, 0))
+ if (get_u32(&if_id, *argv, 0))
+ invarg("if_id value is invalid", *argv);
+ else
addattr32(n, 1024, IFLA_XFRM_IF_ID, if_id);
} else {
xfrm_print_help(lu, argc, argv, stderr);
diff --git a/lib/utils.c b/lib/utils.c
index bbb3bdcfa..c6f19ce1a 100644
--- a/lib/utils.c
+++ b/lib/utils.c
@@ -1451,7 +1451,7 @@ int get_guid(__u64 *guid, const char *arg)
if (tmp > 255)
return -1;
- *guid |= tmp << (56 - 8 * i);
+ *guid |= tmp << (56 - 8 * i);
}
return 0;
diff --git a/man/man8/bridge.8 b/man/man8/bridge.8
index 10f6cf0e1..1804f0b42 100644
--- a/man/man8/bridge.8
+++ b/man/man8/bridge.8
@@ -71,7 +71,7 @@ bridge \- show / manipulate bridge addresses and devices
.B dst
.IR IPADDR " ] [ "
.B src_vni
-.IR SRC_VNI " ] ["
+.IR VNI " ] ["
.B vni
.IR VNI " ] ["
.B port
@@ -498,7 +498,7 @@ the IP address of the destination
VXLAN tunnel endpoint where the Ethernet MAC ADDRESS resides.
.TP
-.BI src_vni " SRC VNI"
+.BI src_vni " VNI"
the src VNI Network Identifier (or VXLAN Segment ID)
this entry belongs to. Used only when the vxlan device is in
external or collect metadata mode. If omitted the value specified at
diff --git a/man/man8/tc-fq.8 b/man/man8/tc-fq.8
index 1febe62bb..27385aaed 100644
--- a/man/man8/tc-fq.8
+++ b/man/man8/tc-fq.8
@@ -90,15 +90,15 @@ Experienced. This is useful for DCTCP-style congestion control algorithms that
require marking at very shallow queueing thresholds.
.SH EXAMPLES
-#tc qdisc add dev eth0 root est 1sec 4sec fq ce_threshold 4ms
+#tc qdisc add dev eth0 root fq ce_threshold 4ms
.br
-#tc -s -d qdisc sh dev eth0
+#tc -s -d qdisc show dev eth0
.br
-qdisc fq 800e: root refcnt 9 limit 10000p flow_limit 1000p buckets 1024 orphan_mask 1023 quantum 3028 initial_quantum 15140 low_rate_threshold 550Kbit refill_delay 40.0ms ce_threshold 4.0ms
- Sent 533368436185 bytes 352296695 pkt (dropped 0, overlimits 0 requeues 1339864)
- rate 39220Mbit 3238202pps backlog 12417828b 358p requeues 1339864
- 1052 flows (852 inactive, 0 throttled)
- 112 gc, 0 highprio, 212 throttled, 21501 ns latency, 470241 ce_mark
+qdisc fq 8001: dev eth0 root refcnt 2 limit 10000p flow_limit 100p buckets 1024 orphan_mask 1023 quantum 3028b initial_quantum 15140b low_rate_threshold 550Kbit refill_delay 40.0ms ce_threshold 4.0ms
+ Sent 72149092 bytes 48062 pkt (dropped 2176, overlimits 0 requeues 0)
+ backlog 1937920b 1280p requeues 0
+ flows 34 (inactive 17 throttled 0)
+ gc 0 highprio 0 throttled 0 ce_mark 47622 flows_plimit 2176
.br
.SH SEE ALSO
.BR tc (8),
diff --git a/man/man8/tc-pie.8 b/man/man8/tc-pie.8
index bdcfba51b..0db97d13b 100644
--- a/man/man8/tc-pie.8
+++ b/man/man8/tc-pie.8
@@ -107,32 +107,32 @@ is turned off.
qdisc pie 8036: dev eth0 root refcnt 2 limit 1000p target 15.0ms tupdate 16.0ms alpha 2 beta 20
Sent 31216108 bytes 20800 pkt (dropped 80, overlimits 0 requeues 0)
backlog 16654b 11p requeues 0
- prob 0.006161 delay 15666us
- pkts_in 20811 overlimit 0 dropped 80 maxq 50 ecn_mark 0
+ prob 0.006161 delay 15666us
+ pkts_in 20811 overlimit 0 dropped 80 maxq 50 ecn_mark 0
# tc qdisc add dev eth0 root pie dq_rate_estimator
# tc -s qdisc show
qdisc pie 8036: dev eth0 root refcnt 2 limit 1000p target 15.0ms tupdate 16.0ms alpha 2 beta 20
Sent 63947420 bytes 42414 pkt (dropped 41, overlimits 0 requeues 0)
backlog 271006b 179p requeues 0
- prob 0.000092 delay 22200us avg_dq_rate 12145996
- pkts_in 41 overlimit 343 dropped 0 maxq 50 ecn_mark 0
+ prob 0.000092 delay 22200us avg_dq_rate 12145996
+ pkts_in 41 overlimit 343 dropped 0 maxq 50 ecn_mark 0
# tc qdisc add dev eth0 root pie limit 100 target 20ms tupdate 30ms ecn
# tc -s qdisc show
qdisc pie 8036: dev eth0 root refcnt 2 limit 100p target 20.0ms tupdate 32.0ms alpha 2 beta 20 ecn
Sent 6591724 bytes 4442 pkt (dropped 27, overlimits 0 requeues 0)
backlog 18168b 12p requeues 0
- prob 0.008845 delay 11348us
- pkts_in 4454 overlimit 0 dropped 27 maxq 65 ecn_mark 0
+ prob 0.008845 delay 11348us
+ pkts_in 4454 overlimit 0 dropped 27 maxq 65 ecn_mark 0
# tc qdisc add dev eth0 root pie limit 100 target 50ms tupdate 30ms bytemode
# tc -s qdisc show
qdisc pie 8036: dev eth0 root refcnt 2 limit 100p target 50.0ms tupdate 32.0ms alpha 2 beta 20 bytemode
Sent 1616274 bytes 1137 pkt (dropped 0, overlimits 0 requeues 0)
backlog 13626b 9p requeues 0
- prob 0.000000 delay 0us
- pkts_in 1146 overlimit 0 dropped 0 maxq 23 ecn_mark 0
+ prob 0.000000 delay 0us
+ pkts_in 1146 overlimit 0 dropped 0 maxq 23 ecn_mark 0
.SH SEE ALSO
.BR tc (8),
diff --git a/tc/q_cbs.c b/tc/q_cbs.c
index 9515a1f7f..13bb08e97 100644
--- a/tc/q_cbs.c
+++ b/tc/q_cbs.c
@@ -125,11 +125,11 @@ static int cbs_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt)
if (RTA_PAYLOAD(tb[TCA_CBS_PARMS]) < sizeof(*qopt))
return -1;
- fprintf(f, "hicredit %d ", qopt->hicredit);
- fprintf(f, "locredit %d ", qopt->locredit);
- fprintf(f, "sendslope %d ", qopt->sendslope);
- fprintf(f, "idleslope %d ", qopt->idleslope);
- fprintf(f, "offload %d ", qopt->offload);
+ print_int(PRINT_ANY, "hicredit", "hicredit %d ", qopt->hicredit);
+ print_int(PRINT_ANY, "locredit", "locredit %d ", qopt->locredit);
+ print_int(PRINT_ANY, "sendslope", "sendslope %d ", qopt->sendslope);
+ print_int(PRINT_ANY, "idleslope", "idleslope %d ", qopt->idleslope);
+ print_int(PRINT_ANY, "offload", "offload %d ", qopt->offload);
return 0;
}
diff --git a/tc/q_choke.c b/tc/q_choke.c
index 648d9ad71..570c3599e 100644
--- a/tc/q_choke.c
+++ b/tc/q_choke.c
@@ -186,18 +186,23 @@ static int choke_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt)
RTA_PAYLOAD(tb[TCA_CHOKE_MAX_P]) >= sizeof(__u32))
max_P = rta_getattr_u32(tb[TCA_CHOKE_MAX_P]);
- fprintf(f, "limit %up min %up max %up ",
- qopt->limit, qopt->qth_min, qopt->qth_max);
+ print_uint(PRINT_ANY, "limit", "limit %up ", qopt->limit);
+ print_uint(PRINT_ANY, "min", "min %up ", qopt->qth_min);
+ print_uint(PRINT_ANY, "max", "max %up ", qopt->qth_max);
tc_red_print_flags(qopt->flags);
if (show_details) {
- fprintf(f, "ewma %u ", qopt->Wlog);
+ print_uint(PRINT_ANY, "ewma", "ewma %u ", qopt->Wlog);
+
if (max_P)
- fprintf(f, "probability %g ", max_P / pow(2, 32));
+ print_float(PRINT_ANY, "probability",
+ "probability %lg ", max_P / pow(2, 32));
else
- fprintf(f, "Plog %u ", qopt->Plog);
- fprintf(f, "Scell_log %u", qopt->Scell_log);
+ print_uint(PRINT_ANY, "Plog", "Plog %u ", qopt->Plog);
+
+ print_uint(PRINT_ANY, "Scell_log", "Scell_log %u",
+ qopt->Scell_log);
}
return 0;
}
@@ -214,8 +219,13 @@ static int choke_print_xstats(struct qdisc_util *qu, FILE *f,
return -1;
st = RTA_DATA(xstats);
- fprintf(f, " marked %u early %u pdrop %u other %u matched %u",
- st->marked, st->early, st->pdrop, st->other, st->matched);
+
+ print_uint(PRINT_ANY, "marked", " marked %u", st->marked);
+ print_uint(PRINT_ANY, "early", " early %u", st->early);
+ print_uint(PRINT_ANY, "pdrop", " pdrop %u", st->pdrop);
+ print_uint(PRINT_ANY, "other", " other %u", st->other);
+ print_uint(PRINT_ANY, "matched", " matched %u", st->matched);
+
return 0;
}
diff --git a/tc/q_codel.c b/tc/q_codel.c
index 849cc0400..c72a5779b 100644
--- a/tc/q_codel.c
+++ b/tc/q_codel.c
@@ -144,28 +144,34 @@ static int codel_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt)
if (tb[TCA_CODEL_LIMIT] &&
RTA_PAYLOAD(tb[TCA_CODEL_LIMIT]) >= sizeof(__u32)) {
limit = rta_getattr_u32(tb[TCA_CODEL_LIMIT]);
- fprintf(f, "limit %up ", limit);
+ print_uint(PRINT_ANY, "limit", "limit %up ", limit);
}
if (tb[TCA_CODEL_TARGET] &&
RTA_PAYLOAD(tb[TCA_CODEL_TARGET]) >= sizeof(__u32)) {
target = rta_getattr_u32(tb[TCA_CODEL_TARGET]);
- fprintf(f, "target %s ", sprint_time(target, b1));
+ print_uint(PRINT_JSON, "target", NULL, target);
+ print_string(PRINT_FP, NULL, "target %s ",
+ sprint_time(target, b1));
}
if (tb[TCA_CODEL_CE_THRESHOLD] &&
RTA_PAYLOAD(tb[TCA_CODEL_CE_THRESHOLD]) >= sizeof(__u32)) {
ce_threshold = rta_getattr_u32(tb[TCA_CODEL_CE_THRESHOLD]);
- fprintf(f, "ce_threshold %s ", sprint_time(ce_threshold, b1));
+ print_uint(PRINT_JSON, "ce_threshold", NULL, ce_threshold);
+ print_string(PRINT_FP, NULL, "ce_threshold %s ",
+ sprint_time(ce_threshold, b1));
}
if (tb[TCA_CODEL_INTERVAL] &&
RTA_PAYLOAD(tb[TCA_CODEL_INTERVAL]) >= sizeof(__u32)) {
interval = rta_getattr_u32(tb[TCA_CODEL_INTERVAL]);
- fprintf(f, "interval %s ", sprint_time(interval, b1));
+ print_uint(PRINT_JSON, "interval", NULL, interval);
+ print_string(PRINT_FP, NULL, "interval %s ",
+ sprint_time(interval, b1));
}
if (tb[TCA_CODEL_ECN] &&
RTA_PAYLOAD(tb[TCA_CODEL_ECN]) >= sizeof(__u32)) {
ecn = rta_getattr_u32(tb[TCA_CODEL_ECN]);
if (ecn)
- fprintf(f, "ecn ");
+ print_bool(PRINT_ANY, "ecn", "ecn ", true);
}
return 0;
@@ -187,18 +193,31 @@ static int codel_print_xstats(struct qdisc_util *qu, FILE *f,
st = &_st;
}
- fprintf(f, " count %u lastcount %u ldelay %s",
- st->count, st->lastcount, sprint_time(st->ldelay, b1));
+ print_uint(PRINT_ANY, "count", " count %u", st->count);
+ print_uint(PRINT_ANY, "lastcount", " lastcount %u", st->lastcount);
+ print_uint(PRINT_JSON, "ldelay", NULL, st->ldelay);
+ print_string(PRINT_FP, NULL, " ldelay %s", sprint_time(st->ldelay, b1));
+
if (st->dropping)
- fprintf(f, " dropping");
+ print_bool(PRINT_ANY, "dropping", " dropping", true);
+
+ print_int(PRINT_JSON, "drop_next", NULL, st->drop_next);
if (st->drop_next < 0)
- fprintf(f, " drop_next -%s", sprint_time(-st->drop_next, b1));
+ print_string(PRINT_FP, NULL, " drop_next -%s",
+ sprint_time(-st->drop_next, b1));
else
- fprintf(f, " drop_next %s", sprint_time(st->drop_next, b1));
- fprintf(f, "\n maxpacket %u ecn_mark %u drop_overlimit %u",
- st->maxpacket, st->ecn_mark, st->drop_overlimit);
+ print_string(PRINT_FP, NULL, " drop_next %s",
+ sprint_time(st->drop_next, b1));
+
+ print_nl();
+ print_uint(PRINT_ANY, "maxpacket", " maxpacket %u", st->maxpacket);
+ print_uint(PRINT_ANY, "ecn_mark", " ecn_mark %u", st->ecn_mark);
+ print_uint(PRINT_ANY, "drop_overlimit", " drop_overlimit %u",
+ st->drop_overlimit);
+
if (st->ce_mark)
- fprintf(f, " ce_mark %u", st->ce_mark);
+ print_uint(PRINT_ANY, "ce_mark", " ce_mark %u", st->ce_mark);
+
return 0;
}
diff --git a/tc/q_fq.c b/tc/q_fq.c
index caf232ec4..44d8a7e03 100644
--- a/tc/q_fq.c
+++ b/tc/q_fq.c
@@ -265,71 +265,94 @@ static int fq_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt)
if (tb[TCA_FQ_PLIMIT] &&
RTA_PAYLOAD(tb[TCA_FQ_PLIMIT]) >= sizeof(__u32)) {
plimit = rta_getattr_u32(tb[TCA_FQ_PLIMIT]);
- fprintf(f, "limit %up ", plimit);
+ print_uint(PRINT_ANY, "limit", "limit %up ", plimit);
}
if (tb[TCA_FQ_FLOW_PLIMIT] &&
RTA_PAYLOAD(tb[TCA_FQ_FLOW_PLIMIT]) >= sizeof(__u32)) {
flow_plimit = rta_getattr_u32(tb[TCA_FQ_FLOW_PLIMIT]);
- fprintf(f, "flow_limit %up ", flow_plimit);
+ print_uint(PRINT_ANY, "flow_limit", "flow_limit %up ",
+ flow_plimit);
}
if (tb[TCA_FQ_BUCKETS_LOG] &&
RTA_PAYLOAD(tb[TCA_FQ_BUCKETS_LOG]) >= sizeof(__u32)) {
buckets_log = rta_getattr_u32(tb[TCA_FQ_BUCKETS_LOG]);
- fprintf(f, "buckets %u ", 1U << buckets_log);
+ print_uint(PRINT_ANY, "buckets", "buckets %u ",
+ 1U << buckets_log);
}
if (tb[TCA_FQ_ORPHAN_MASK] &&
RTA_PAYLOAD(tb[TCA_FQ_ORPHAN_MASK]) >= sizeof(__u32)) {
orphan_mask = rta_getattr_u32(tb[TCA_FQ_ORPHAN_MASK]);
- fprintf(f, "orphan_mask %u ", orphan_mask);
+ print_uint(PRINT_ANY, "orphan_mask", "orphan_mask %u ",
+ orphan_mask);
}
if (tb[TCA_FQ_RATE_ENABLE] &&
RTA_PAYLOAD(tb[TCA_FQ_RATE_ENABLE]) >= sizeof(int)) {
pacing = rta_getattr_u32(tb[TCA_FQ_RATE_ENABLE]);
if (pacing == 0)
- fprintf(f, "nopacing ");
+ print_bool(PRINT_ANY, "pacing", "nopacing ", false);
}
if (tb[TCA_FQ_QUANTUM] &&
RTA_PAYLOAD(tb[TCA_FQ_QUANTUM]) >= sizeof(__u32)) {
quantum = rta_getattr_u32(tb[TCA_FQ_QUANTUM]);
- fprintf(f, "quantum %u ", quantum);
+ print_uint(PRINT_JSON, "quantum", NULL, quantum);
+ print_string(PRINT_FP, NULL, "quantum %s ",
+ sprint_size(quantum, b1));
}
if (tb[TCA_FQ_INITIAL_QUANTUM] &&
RTA_PAYLOAD(tb[TCA_FQ_INITIAL_QUANTUM]) >= sizeof(__u32)) {
quantum = rta_getattr_u32(tb[TCA_FQ_INITIAL_QUANTUM]);
- fprintf(f, "initial_quantum %u ", quantum);
+ print_uint(PRINT_JSON, "initial_quantum", NULL, quantum);
+ print_string(PRINT_FP, NULL, "initial_quantum %s ",
+ sprint_size(quantum, b1));
}
if (tb[TCA_FQ_FLOW_MAX_RATE] &&
RTA_PAYLOAD(tb[TCA_FQ_FLOW_MAX_RATE]) >= sizeof(__u32)) {
rate = rta_getattr_u32(tb[TCA_FQ_FLOW_MAX_RATE]);
- if (rate != ~0U)
- fprintf(f, "maxrate %s ", sprint_rate(rate, b1));
+ if (rate != ~0U) {
+ print_uint(PRINT_JSON, "maxrate", NULL, rate);
+ print_string(PRINT_FP, NULL, "maxrate %s ",
+ sprint_rate(rate, b1));
+ }
}
if (tb[TCA_FQ_FLOW_DEFAULT_RATE] &&
RTA_PAYLOAD(tb[TCA_FQ_FLOW_DEFAULT_RATE]) >= sizeof(__u32)) {
rate = rta_getattr_u32(tb[TCA_FQ_FLOW_DEFAULT_RATE]);
- if (rate != 0)
- fprintf(f, "defrate %s ", sprint_rate(rate, b1));
+ if (rate != 0) {
+ print_uint(PRINT_JSON, "defrate", NULL, rate);
+ print_string(PRINT_FP, NULL, "defrate %s ",
+ sprint_rate(rate, b1));
+ }
}
if (tb[TCA_FQ_LOW_RATE_THRESHOLD] &&
RTA_PAYLOAD(tb[TCA_FQ_LOW_RATE_THRESHOLD]) >= sizeof(__u32)) {
rate = rta_getattr_u32(tb[TCA_FQ_LOW_RATE_THRESHOLD]);
- if (rate != 0)
- fprintf(f, "low_rate_threshold %s ", sprint_rate(rate, b1));
+ if (rate != 0) {
+ print_uint(PRINT_JSON, "low_rate_threshold", NULL,
+ rate);
+ print_string(PRINT_FP, NULL, "low_rate_threshold %s ",
+ sprint_rate(rate, b1));
+ }
}
if (tb[TCA_FQ_FLOW_REFILL_DELAY] &&
RTA_PAYLOAD(tb[TCA_FQ_FLOW_REFILL_DELAY]) >= sizeof(__u32)) {
refill_delay = rta_getattr_u32(tb[TCA_FQ_FLOW_REFILL_DELAY]);
- fprintf(f, "refill_delay %s ", sprint_time(refill_delay, b1));
+ print_uint(PRINT_JSON, "refill_delay", NULL, refill_delay);
+ print_string(PRINT_FP, NULL, "refill_delay %s ",
+ sprint_time(refill_delay, b1));
}
if (tb[TCA_FQ_CE_THRESHOLD] &&
RTA_PAYLOAD(tb[TCA_FQ_CE_THRESHOLD]) >= sizeof(__u32)) {
ce_threshold = rta_getattr_u32(tb[TCA_FQ_CE_THRESHOLD]);
- if (ce_threshold != ~0U)
- fprintf(f, "ce_threshold %s ", sprint_time(ce_threshold, b1));
+ if (ce_threshold != ~0U) {
+ print_uint(PRINT_JSON, "ce_threshold", NULL,
+ ce_threshold);
+ print_string(PRINT_FP, NULL, "ce_threshold %s ",
+ sprint_time(ce_threshold, b1));
+ }
}
return 0;
@@ -340,6 +363,8 @@ static int fq_print_xstats(struct qdisc_util *qu, FILE *f,
{
struct tc_fq_qd_stats *st, _st;
+ SPRINT_BUF(b1);
+
if (xstats == NULL)
return 0;
@@ -348,32 +373,51 @@ static int fq_print_xstats(struct qdisc_util *qu, FILE *f,
st = &_st;
- fprintf(f, " %u flows (%u inactive, %u throttled)",
- st->flows, st->inactive_flows, st->throttled_flows);
+ print_uint(PRINT_ANY, "flows", " flows %u", st->flows);
+ print_uint(PRINT_ANY, "inactive", " (inactive %u", st->inactive_flows);
+ print_uint(PRINT_ANY, "throttled", " throttled %u)",
+ st->throttled_flows);
- if (st->time_next_delayed_flow > 0)
- fprintf(f, ", next packet delay %llu ns", st->time_next_delayed_flow);
+ if (st->time_next_delayed_flow > 0) {
+ print_lluint(PRINT_JSON, "next_packet_delay", NULL,
+ st->time_next_delayed_flow);
+ print_string(PRINT_FP, NULL, " next_packet_delay %s",
+ sprint_time64(st->time_next_delayed_flow, b1));
+ }
- fprintf(f, "\n %llu gc, %llu highprio",
- st->gc_flows, st->highprio_packets);
+ print_nl();
+ print_lluint(PRINT_ANY, "gc", " gc %llu", st->gc_flows);
+ print_lluint(PRINT_ANY, "highprio", " highprio %llu",
+ st->highprio_packets);
if (st->tcp_retrans)
- fprintf(f, ", %llu retrans", st->tcp_retrans);
+ print_lluint(PRINT_ANY, "retrans", " retrans %llu",
+ st->tcp_retrans);
- fprintf(f, ", %llu throttled", st->throttled);
+ print_lluint(PRINT_ANY, "throttled", " throttled %llu", st->throttled);
- if (st->unthrottle_latency_ns)
- fprintf(f, ", %u ns latency", st->unthrottle_latency_ns);
+ if (st->unthrottle_latency_ns) {
+ print_uint(PRINT_JSON, "latency", NULL,
+ st->unthrottle_latency_ns);
+ print_string(PRINT_FP, NULL, " latency %s",
+ sprint_time64(st->unthrottle_latency_ns, b1));
+ }
if (st->ce_mark)
- fprintf(f, ", %llu ce_mark", st->ce_mark);
+ print_lluint(PRINT_ANY, "ce_mark", " ce_mark %llu",
+ st->ce_mark);
if (st->flows_plimit)
- fprintf(f, ", %llu flows_plimit", st->flows_plimit);
-
- if (st->pkts_too_long || st->allocation_errors)
- fprintf(f, "\n %llu too long pkts, %llu alloc errors\n",
- st->pkts_too_long, st->allocation_errors);
+ print_lluint(PRINT_ANY, "flows_plimit", " flows_plimit %llu",
+ st->flows_plimit);
+
+ if (st->pkts_too_long || st->allocation_errors) {
+ print_nl();
+ print_lluint(PRINT_ANY, "pkts_too_long",
+ " pkts_too_long %llu", st->pkts_too_long);
+ print_lluint(PRINT_ANY, "alloc_errors", " alloc_erros %llu",
+ st->allocation_errors);
+ }
return 0;
}
diff --git a/tc/q_fq_codel.c b/tc/q_fq_codel.c
index 12ce3fbfd..efed4d289 100644
--- a/tc/q_fq_codel.c
+++ b/tc/q_fq_codel.c
@@ -276,12 +276,12 @@ static int fq_codel_print_xstats(struct qdisc_util *qu, FILE *f,
sprint_time(st->class_stats.ldelay, b1));
if (st->class_stats.dropping) {
print_bool(PRINT_ANY, "dropping", " dropping", true);
+ print_int(PRINT_JSON, "drop_next", NULL,
+ st->class_stats.drop_next);
if (st->class_stats.drop_next < 0)
print_string(PRINT_FP, NULL, " drop_next -%s",
sprint_time(-st->class_stats.drop_next, b1));
else {
- print_uint(PRINT_JSON, "drop_next", NULL,
- st->class_stats.drop_next);
print_string(PRINT_FP, NULL, " drop_next %s",
sprint_time(st->class_stats.drop_next, b1));
}
diff --git a/tc/q_hhf.c b/tc/q_hhf.c
index 5ee6642f2..f88880117 100644
--- a/tc/q_hhf.c
+++ b/tc/q_hhf.c
@@ -138,37 +138,46 @@ static int hhf_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt)
if (tb[TCA_HHF_BACKLOG_LIMIT] &&
RTA_PAYLOAD(tb[TCA_HHF_BACKLOG_LIMIT]) >= sizeof(__u32)) {
limit = rta_getattr_u32(tb[TCA_HHF_BACKLOG_LIMIT]);
- fprintf(f, "limit %up ", limit);
+ print_uint(PRINT_ANY, "limit", "limit %up ", limit);
}
if (tb[TCA_HHF_QUANTUM] &&
RTA_PAYLOAD(tb[TCA_HHF_QUANTUM]) >= sizeof(__u32)) {
quantum = rta_getattr_u32(tb[TCA_HHF_QUANTUM]);
- fprintf(f, "quantum %u ", quantum);
+ print_uint(PRINT_JSON, "quantum", NULL, quantum);
+ print_string(PRINT_FP, NULL, "quantum %s ",
+ sprint_size(quantum, b1));
}
if (tb[TCA_HHF_HH_FLOWS_LIMIT] &&
RTA_PAYLOAD(tb[TCA_HHF_HH_FLOWS_LIMIT]) >= sizeof(__u32)) {
hh_limit = rta_getattr_u32(tb[TCA_HHF_HH_FLOWS_LIMIT]);
- fprintf(f, "hh_limit %u ", hh_limit);
+ print_uint(PRINT_ANY, "hh_limit", "hh_limit %u ", hh_limit);
}
if (tb[TCA_HHF_RESET_TIMEOUT] &&
RTA_PAYLOAD(tb[TCA_HHF_RESET_TIMEOUT]) >= sizeof(__u32)) {
reset_timeout = rta_getattr_u32(tb[TCA_HHF_RESET_TIMEOUT]);
- fprintf(f, "reset_timeout %s ", sprint_time(reset_timeout, b1));
+ print_uint(PRINT_JSON, "reset_timeout", NULL, reset_timeout);
+ print_string(PRINT_FP, NULL, "reset_timeout %s ",
+ sprint_time(reset_timeout, b1));
}
if (tb[TCA_HHF_ADMIT_BYTES] &&
RTA_PAYLOAD(tb[TCA_HHF_ADMIT_BYTES]) >= sizeof(__u32)) {
admit_bytes = rta_getattr_u32(tb[TCA_HHF_ADMIT_BYTES]);
- fprintf(f, "admit_bytes %u ", admit_bytes);
+ print_uint(PRINT_JSON, "admit_bytes", NULL, admit_bytes);
+ print_string(PRINT_FP, NULL, "admit_bytes %s ",
+ sprint_size(admit_bytes, b1));
}
if (tb[TCA_HHF_EVICT_TIMEOUT] &&
RTA_PAYLOAD(tb[TCA_HHF_EVICT_TIMEOUT]) >= sizeof(__u32)) {
evict_timeout = rta_getattr_u32(tb[TCA_HHF_EVICT_TIMEOUT]);
- fprintf(f, "evict_timeout %s ", sprint_time(evict_timeout, b1));
+ print_uint(PRINT_JSON, "evict_timeout", NULL, evict_timeout);
+ print_string(PRINT_FP, NULL, "evict_timeout %s ",
+ sprint_time(evict_timeout, b1));
}
if (tb[TCA_HHF_NON_HH_WEIGHT] &&
RTA_PAYLOAD(tb[TCA_HHF_NON_HH_WEIGHT]) >= sizeof(__u32)) {
non_hh_weight = rta_getattr_u32(tb[TCA_HHF_NON_HH_WEIGHT]);
- fprintf(f, "non_hh_weight %u ", non_hh_weight);
+ print_uint(PRINT_ANY, "non_hh_weight", "non_hh_weight %u ",
+ non_hh_weight);
}
return 0;
}
@@ -186,9 +195,13 @@ static int hhf_print_xstats(struct qdisc_util *qu, FILE *f,
st = RTA_DATA(xstats);
- fprintf(f, " drop_overlimit %u hh_overlimit %u tot_hh %u cur_hh %u",
- st->drop_overlimit, st->hh_overlimit,
- st->hh_tot_count, st->hh_cur_count);
+ print_uint(PRINT_ANY, "drop_overlimit", " drop_overlimit %u",
+ st->drop_overlimit);
+ print_uint(PRINT_ANY, "hh_overlimit", " hh_overlimit %u",
+ st->hh_overlimit);
+ print_uint(PRINT_ANY, "tot_hh", " tot_hh %u", st->hh_tot_count);
+ print_uint(PRINT_ANY, "cur_hh", " cur_hh %u", st->hh_cur_count);
+
return 0;
}
diff --git a/tc/q_pie.c b/tc/q_pie.c
index fda98a718..709a78b4c 100644
--- a/tc/q_pie.c
+++ b/tc/q_pie.c
@@ -156,40 +156,44 @@ static int pie_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt)
if (tb[TCA_PIE_LIMIT] &&
RTA_PAYLOAD(tb[TCA_PIE_LIMIT]) >= sizeof(__u32)) {
limit = rta_getattr_u32(tb[TCA_PIE_LIMIT]);
- fprintf(f, "limit %up ", limit);
+ print_uint(PRINT_ANY, "limit", "limit %up ", limit);
}
if (tb[TCA_PIE_TARGET] &&
RTA_PAYLOAD(tb[TCA_PIE_TARGET]) >= sizeof(__u32)) {
target = rta_getattr_u32(tb[TCA_PIE_TARGET]);
- fprintf(f, "target %s ", sprint_time(target, b1));
+ print_uint(PRINT_JSON, "target", NULL, target);
+ print_string(PRINT_FP, NULL, "target %s ",
+ sprint_time(target, b1));
}
if (tb[TCA_PIE_TUPDATE] &&
RTA_PAYLOAD(tb[TCA_PIE_TUPDATE]) >= sizeof(__u32)) {
tupdate = rta_getattr_u32(tb[TCA_PIE_TUPDATE]);
- fprintf(f, "tupdate %s ", sprint_time(tupdate, b1));
+ print_uint(PRINT_JSON, "tupdate", NULL, tupdate);
+ print_string(PRINT_FP, NULL, "tupdate %s ",
+ sprint_time(tupdate, b1));
}
if (tb[TCA_PIE_ALPHA] &&
RTA_PAYLOAD(tb[TCA_PIE_ALPHA]) >= sizeof(__u32)) {
alpha = rta_getattr_u32(tb[TCA_PIE_ALPHA]);
- fprintf(f, "alpha %u ", alpha);
+ print_uint(PRINT_ANY, "alpha", "alpha %u ", alpha);
}
if (tb[TCA_PIE_BETA] &&
RTA_PAYLOAD(tb[TCA_PIE_BETA]) >= sizeof(__u32)) {
beta = rta_getattr_u32(tb[TCA_PIE_BETA]);
- fprintf(f, "beta %u ", beta);
+ print_uint(PRINT_ANY, "beta", "beta %u ", beta);
}
if (tb[TCA_PIE_ECN] && RTA_PAYLOAD(tb[TCA_PIE_ECN]) >= sizeof(__u32)) {
ecn = rta_getattr_u32(tb[TCA_PIE_ECN]);
if (ecn)
- fprintf(f, "ecn ");
+ print_bool(PRINT_ANY, "ecn", "ecn ", true);
}
if (tb[TCA_PIE_BYTEMODE] &&
RTA_PAYLOAD(tb[TCA_PIE_BYTEMODE]) >= sizeof(__u32)) {
bytemode = rta_getattr_u32(tb[TCA_PIE_BYTEMODE]);
if (bytemode)
- fprintf(f, "bytemode ");
+ print_bool(PRINT_ANY, "bytemode", "bytemode ", true);
}
if (tb[TCA_PIE_DQ_RATE_ESTIMATOR] &&
@@ -197,7 +201,8 @@ static int pie_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt)
dq_rate_estimator =
rta_getattr_u32(tb[TCA_PIE_DQ_RATE_ESTIMATOR]);
if (dq_rate_estimator)
- fprintf(f, "dq_rate_estimator ");
+ print_bool(PRINT_ANY, "dq_rate_estimator",
+ "dq_rate_estimator ", true);
}
return 0;
@@ -208,6 +213,8 @@ static int pie_print_xstats(struct qdisc_util *qu, FILE *f,
{
struct tc_pie_xstats *st;
+ SPRINT_BUF(b1);
+
if (xstats == NULL)
return 0;
@@ -215,18 +222,24 @@ static int pie_print_xstats(struct qdisc_util *qu, FILE *f,
return -1;
st = RTA_DATA(xstats);
- /*prob is returned as a fracion of maximum integer value */
- fprintf(f, "prob %f delay %uus",
- (double)st->prob / (double)UINT64_MAX, st->delay);
+
+ /* prob is returned as a fracion of maximum integer value */
+ print_float(PRINT_ANY, "prob", " prob %lg",
+ (double)st->prob / (double)UINT64_MAX);
+ print_uint(PRINT_JSON, "delay", NULL, st->delay);
+ print_string(PRINT_FP, NULL, " delay %s", sprint_time(st->delay, b1));
if (st->dq_rate_estimating)
- fprintf(f, " avg_dq_rate %u\n", st->avg_dq_rate);
- else
- fprintf(f, "\n");
+ print_uint(PRINT_ANY, "avg_dq_rate", " avg_dq_rate %u",
+ st->avg_dq_rate);
+
+ print_nl();
+ print_uint(PRINT_ANY, "pkts_in", " pkts_in %u", st->packets_in);
+ print_uint(PRINT_ANY, "overlimit", " overlimit %u", st->overlimit);
+ print_uint(PRINT_ANY, "dropped", " dropped %u", st->dropped);
+ print_uint(PRINT_ANY, "maxq", " maxq %u", st->maxq);
+ print_uint(PRINT_ANY, "ecn_mark", " ecn_mark %u", st->ecn_mark);
- fprintf(f, "pkts_in %u overlimit %u dropped %u maxq %u ecn_mark %u\n",
- st->packets_in, st->overlimit, st->dropped, st->maxq,
- st->ecn_mark);
return 0;
}
diff --git a/tc/q_sfb.c b/tc/q_sfb.c
index 7f48c6e0e..8af55d98c 100644
--- a/tc/q_sfb.c
+++ b/tc/q_sfb.c
@@ -143,6 +143,8 @@ static int sfb_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt)
struct rtattr *tb[__TCA_SFB_MAX];
struct tc_sfb_qopt *qopt;
+ SPRINT_BUF(b1);
+
if (opt == NULL)
return 0;
@@ -153,14 +155,27 @@ static int sfb_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt)
if (RTA_PAYLOAD(tb[TCA_SFB_PARMS]) < sizeof(*qopt))
return -1;
- fprintf(f,
- "limit %d max %d target %d\n"
- " increment %.5f decrement %.5f penalty rate %d burst %d (%ums %ums)",
- qopt->limit, qopt->max, qopt->bin_size,
- (double)qopt->increment / SFB_MAX_PROB,
- (double)qopt->decrement / SFB_MAX_PROB,
- qopt->penalty_rate, qopt->penalty_burst,
- qopt->rehash_interval, qopt->warmup_time);
+ print_uint(PRINT_JSON, "rehash", NULL, qopt->rehash_interval * 1000);
+ print_string(PRINT_FP, NULL, "rehash %s ",
+ sprint_time(qopt->rehash_interval * 1000, b1));
+
+ print_uint(PRINT_JSON, "db", NULL, qopt->warmup_time * 1000);
+ print_string(PRINT_FP, NULL, "db %s ",
+ sprint_time(qopt->warmup_time * 1000, b1));
+
+ print_uint(PRINT_ANY, "limit", "limit %up ", qopt->limit);
+ print_uint(PRINT_ANY, "max", "max %up ", qopt->max);
+ print_uint(PRINT_ANY, "target", "target %up ", qopt->bin_size);
+
+ print_float(PRINT_ANY, "increment", "increment %lg ",
+ (double)qopt->increment / SFB_MAX_PROB);
+ print_float(PRINT_ANY, "decrement", "decrement %lg ",
+ (double)qopt->decrement / SFB_MAX_PROB);
+
+ print_uint(PRINT_ANY, "penalty_rate", "penalty_rate %upps ",
+ qopt->penalty_rate);
+ print_uint(PRINT_ANY, "penalty_burst", "penalty_burst %up ",
+ qopt->penalty_burst);
return 0;
}
@@ -168,24 +183,32 @@ static int sfb_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt)
static int sfb_print_xstats(struct qdisc_util *qu, FILE *f,
struct rtattr *xstats)
{
- struct tc_sfb_xstats *st;
+ struct tc_sfb_xstats *st;
- if (xstats == NULL)
- return 0;
+ if (xstats == NULL)
+ return 0;
+
+ if (RTA_PAYLOAD(xstats) < sizeof(*st))
+ return -1;
- if (RTA_PAYLOAD(xstats) < sizeof(*st))
- return -1;
+ st = RTA_DATA(xstats);
- st = RTA_DATA(xstats);
- fprintf(f,
- " earlydrop %u penaltydrop %u bucketdrop %u queuedrop %u childdrop %u marked %u\n"
- " maxqlen %u maxprob %.5f avgprob %.5f ",
- st->earlydrop, st->penaltydrop, st->bucketdrop, st->queuedrop, st->childdrop,
- st->marked,
- st->maxqlen, (double)st->maxprob / SFB_MAX_PROB,
- (double)st->avgprob / SFB_MAX_PROB);
+ print_uint(PRINT_ANY, "earlydrop", " earlydrop %u", st->earlydrop);
+ print_uint(PRINT_ANY, "penaltydrop", " penaltydrop %u",
+ st->penaltydrop);
+ print_uint(PRINT_ANY, "bucketdrop", " bucketdrop %u", st->bucketdrop);
+ print_uint(PRINT_ANY, "queuedrop", " queuedrop %u", st->queuedrop);
+ print_uint(PRINT_ANY, "childdrop", " childdrop %u", st->childdrop);
+ print_uint(PRINT_ANY, "marked", " marked %u", st->marked);
+ print_nl();
+ print_uint(PRINT_ANY, "maxqlen", " maxqlen %u", st->maxqlen);
- return 0;
+ print_float(PRINT_ANY, "maxprob", " maxprob %lg",
+ (double)st->maxprob / SFB_MAX_PROB);
+ print_float(PRINT_ANY, "avgprob", " avgprob %lg",
+ (double)st->avgprob / SFB_MAX_PROB);
+
+ return 0;
}
struct qdisc_util sfb_qdisc_util = {
diff --git a/tc/q_sfq.c b/tc/q_sfq.c
index 4998921d3..2b9bbcd23 100644
--- a/tc/q_sfq.c
+++ b/tc/q_sfq.c
@@ -217,35 +217,53 @@ static int sfq_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt)
if (RTA_PAYLOAD(opt) >= sizeof(*qopt_ext))
qopt_ext = RTA_DATA(opt);
qopt = RTA_DATA(opt);
- fprintf(f, "limit %up ", qopt->limit);
- fprintf(f, "quantum %s ", sprint_size(qopt->quantum, b1));
+
+ print_uint(PRINT_ANY, "limit", "limit %up ", qopt->limit);
+ print_uint(PRINT_JSON, "quantum", NULL, qopt->quantum);
+ print_string(PRINT_FP, NULL, "quantum %s ",
+ sprint_size(qopt->quantum, b1));
+
if (qopt_ext && qopt_ext->depth)
- fprintf(f, "depth %u ", qopt_ext->depth);
+ print_uint(PRINT_ANY, "depth", "depth %u ", qopt_ext->depth);
if (qopt_ext && qopt_ext->headdrop)
- fprintf(f, "headdrop ");
+ print_bool(PRINT_ANY, "headdrop", "headdrop ", true);
+ if (show_details)
+ print_uint(PRINT_ANY, "flows", "flows %u ", qopt->flows);
+
+ print_uint(PRINT_ANY, "divisor", "divisor %u ", qopt->divisor);
- if (show_details) {
- fprintf(f, "flows %u/%u ", qopt->flows, qopt->divisor);
- }
- fprintf(f, "divisor %u ", qopt->divisor);
if (qopt->perturb_period)
- fprintf(f, "perturb %dsec ", qopt->perturb_period);
+ print_int(PRINT_ANY, "perturb", "perturb %dsec ",
+ qopt->perturb_period);
if (qopt_ext && qopt_ext->qth_min) {
- fprintf(f, "\n ewma %u ", qopt_ext->Wlog);
- fprintf(f, "min %s max %s probability %g ",
- sprint_size(qopt_ext->qth_min, b2),
- sprint_size(qopt_ext->qth_max, b3),
- qopt_ext->max_P / pow(2, 32));
+ print_uint(PRINT_ANY, "ewma", "ewma %u ", qopt_ext->Wlog);
+ print_uint(PRINT_JSON, "min", NULL, qopt_ext->qth_min);
+ print_string(PRINT_FP, NULL, "min %s ",
+ sprint_size(qopt_ext->qth_min, b2));
+ print_uint(PRINT_JSON, "max", NULL, qopt_ext->qth_max);
+ print_string(PRINT_FP, NULL, "max %s ",
+ sprint_size(qopt_ext->qth_max, b3));
+ print_float(PRINT_ANY, "probability", "probability %lg ",
+ qopt_ext->max_P / pow(2, 32));
tc_red_print_flags(qopt_ext->flags);
if (show_stats) {
- fprintf(f, "\n prob_mark %u prob_mark_head %u prob_drop %u",
- qopt_ext->stats.prob_mark,
- qopt_ext->stats.prob_mark_head,
- qopt_ext->stats.prob_drop);
- fprintf(f, "\n forced_mark %u forced_mark_head %u forced_drop %u",
- qopt_ext->stats.forced_mark,
- qopt_ext->stats.forced_mark_head,
- qopt_ext->stats.forced_drop);
+ print_nl();
+ print_uint(PRINT_ANY, "prob_mark", " prob_mark %u",
+ qopt_ext->stats.prob_mark);
+ print_uint(PRINT_ANY, "prob_mark_head",
+ " prob_mark_head %u",
+ qopt_ext->stats.prob_mark_head);
+ print_uint(PRINT_ANY, "prob_drop", " prob_drop %u",
+ qopt_ext->stats.prob_drop);
+ print_nl();
+ print_uint(PRINT_ANY, "forced_mark",
+ " forced_mark %u",
+ qopt_ext->stats.forced_mark);
+ print_uint(PRINT_ANY, "forced_mark_head",
+ " forced_mark_head %u",
+ qopt_ext->stats.forced_mark_head);
+ print_uint(PRINT_ANY, "forced_drop", " forced_drop %u",
+ qopt_ext->stats.forced_drop);
}
}
return 0;
@@ -262,8 +280,8 @@ static int sfq_print_xstats(struct qdisc_util *qu, FILE *f,
return -1;
st = RTA_DATA(xstats);
- fprintf(f, " allot %d ", st->allot);
- fprintf(f, "\n");
+ print_int(PRINT_ANY, "allot", " allot %d", st->allot);
+
return 0;
}
diff --git a/tc/q_tbf.c b/tc/q_tbf.c
index 57a9736ca..5135b1d67 100644
--- a/tc/q_tbf.c
+++ b/tc/q_tbf.c
@@ -264,7 +264,7 @@ static int tbf_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt)
struct tc_tbf_qopt *qopt;
unsigned int linklayer;
double buffer, mtu;
- double latency;
+ double latency, lat2;
__u64 rate64 = 0, prate64 = 0;
SPRINT_BUF(b1);
@@ -286,53 +286,79 @@ static int tbf_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt)
if (tb[TCA_TBF_RATE64] &&
RTA_PAYLOAD(tb[TCA_TBF_RATE64]) >= sizeof(rate64))
rate64 = rta_getattr_u64(tb[TCA_TBF_RATE64]);
- fprintf(f, "rate %s ", sprint_rate(rate64, b1));
+ print_u64(PRINT_JSON, "rate", NULL, rate64);
+ print_string(PRINT_FP, NULL, "rate %s ", sprint_rate(rate64, b1));
buffer = tc_calc_xmitsize(rate64, qopt->buffer);
if (show_details) {
- fprintf(f, "burst %s/%u mpu %s ", sprint_size(buffer, b1),
- 1<<qopt->rate.cell_log, sprint_size(qopt->rate.mpu, b2));
+ sprintf(b1, "%s/%u", sprint_size(buffer, b2),
+ 1 << qopt->rate.cell_log);
+ print_string(PRINT_ANY, "burst", "burst %s ", b1);
+ print_uint(PRINT_JSON, "mpu", NULL, qopt->rate.mpu);
+ print_string(PRINT_FP, NULL, "mpu %s ",
+ sprint_size(qopt->rate.mpu, b1));
} else {
- fprintf(f, "burst %s ", sprint_size(buffer, b1));
+ print_u64(PRINT_JSON, "burst", NULL, buffer);
+ print_string(PRINT_FP, NULL, "burst %s ",
+ sprint_size(buffer, b1));
}
if (show_raw)
- fprintf(f, "[%08x] ", qopt->buffer);
+ print_hex(PRINT_ANY, "burst_raw", "[%08x] ", qopt->buffer);
prate64 = qopt->peakrate.rate;
if (tb[TCA_TBF_PRATE64] &&
RTA_PAYLOAD(tb[TCA_TBF_PRATE64]) >= sizeof(prate64))
prate64 = rta_getattr_u64(tb[TCA_TBF_PRATE64]);
if (prate64) {
- fprintf(f, "peakrate %s ", sprint_rate(prate64, b1));
+ print_u64(PRINT_JSON, "peakrate", NULL, prate64);
+ print_string(PRINT_FP, NULL, "peakrate %s ",
+ sprint_rate(prate64, b1));
if (qopt->mtu || qopt->peakrate.mpu) {
mtu = tc_calc_xmitsize(prate64, qopt->mtu);
if (show_details) {
- fprintf(f, "mtu %s/%u mpu %s ", sprint_size(mtu, b1),
- 1<<qopt->peakrate.cell_log, sprint_size(qopt->peakrate.mpu, b2));
+ sprintf(b1, "%s/%u", sprint_size(mtu, b2),
+ 1 << qopt->peakrate.cell_log);
+ print_string(PRINT_ANY, "mtu", "mtu %s ", b1);
+ print_uint(PRINT_JSON, "mpu", NULL,
+ qopt->peakrate.mpu);
+ print_string(PRINT_FP, NULL, "mpu %s ",
+ sprint_size(qopt->peakrate.mpu,
+ b1));
} else {
- fprintf(f, "minburst %s ", sprint_size(mtu, b1));
+ print_u64(PRINT_JSON, "minburst", NULL, mtu);
+ print_string(PRINT_FP, NULL, "minburst %s ",
+ sprint_size(mtu, b1));
}
if (show_raw)
- fprintf(f, "[%08x] ", qopt->mtu);
+ print_hex(PRINT_ANY, "mtu_raw", "[%08x] ",
+ qopt->mtu);
}
}
- latency = TIME_UNITS_PER_SEC*(qopt->limit/(double)rate64) - tc_core_tick2time(qopt->buffer);
+ latency = TIME_UNITS_PER_SEC * (qopt->limit / (double)rate64) -
+ tc_core_tick2time(qopt->buffer);
if (prate64) {
- double lat2 = TIME_UNITS_PER_SEC*(qopt->limit/(double)prate64) - tc_core_tick2time(qopt->mtu);
+ lat2 = TIME_UNITS_PER_SEC * (qopt->limit / (double)prate64) -
+ tc_core_tick2time(qopt->mtu);
if (lat2 > latency)
latency = lat2;
}
- if (latency >= 0.0)
- fprintf(f, "lat %s ", sprint_time(latency, b1));
- if (show_raw || latency < 0.0)
- fprintf(f, "limit %s ", sprint_size(qopt->limit, b1));
-
- if (qopt->rate.overhead) {
- fprintf(f, "overhead %d", qopt->rate.overhead);
+ if (latency >= 0.0) {
+ print_u64(PRINT_JSON, "lat", NULL, latency);
+ print_string(PRINT_FP, NULL, "lat %s ",
+ sprint_time(latency, b1));
+ }
+ if (show_raw || latency < 0.0) {
+ print_uint(PRINT_JSON, "limit", NULL, qopt->limit);
+ print_string(PRINT_FP, NULL, "limit %s ",
+ sprint_size(qopt->limit, b1));
}
+ if (qopt->rate.overhead)
+ print_int(PRINT_ANY, "overhead", "overhead %d ",
+ qopt->rate.overhead);
linklayer = (qopt->rate.linklayer & TC_LINKLAYER_MASK);
if (linklayer > TC_LINKLAYER_ETHERNET || show_details)
- fprintf(f, "linklayer %s ", sprint_linklayer(linklayer, b3));
+ print_string(PRINT_ANY, "linklayer", "linklayer %s ",
+ sprint_linklayer(linklayer, b3));
return 0;
}
diff --git a/testsuite/Makefile b/testsuite/Makefile
index 4451f3169..fb50f618a 100644
--- a/testsuite/Makefile
+++ b/testsuite/Makefile
@@ -82,7 +82,8 @@ endif
TMP_OUT=`mktemp /tmp/tc_testsuite.XXXXXX`; \
. $(KENVFN); \
STD_ERR="$$TMP_ERR" STD_OUT="$$TMP_OUT" \
- TC="$$i/tc/tc" IP="$$i/ip/ip" SS=$$i/misc/ss DEV="$(DEV)" IPVER="$@" SNAME="$$i" \
+ TC="$$i/tc/tc" IP="$$i/ip/ip" SS=$$i/misc/ss BRIDGE="$$i/bridge/bridge" \
+ DEV="$(DEV)" IPVER="$@" SNAME="$$i" \
ERRF="$(RESULTS_DIR)/$@.$$o.err" $(PREFIX) tests/$@ > $(RESULTS_DIR)/$@.$$o.out; \
if [ "$$?" = "127" ]; then \
printf "\033[1;35mSKIPPED\033[0m\n"; \
diff --git a/testsuite/lib/generic.sh b/testsuite/lib/generic.sh
index f92260fc4..8b339ec17 100644
--- a/testsuite/lib/generic.sh
+++ b/testsuite/lib/generic.sh
@@ -1,4 +1,3 @@
-
export DEST="127.0.0.1"
ts_log()
@@ -66,6 +65,11 @@ ts_ss()
__ts_cmd "$SS" "$@"
}
+ts_bridge()
+{
+ __ts_cmd "$BRIDGE" "$@"
+}
+
ts_qdisc_available()
{
HELPOUT=`$TC qdisc add $1 help 2>&1`
@@ -121,7 +125,7 @@ test_on_not()
test_lines_count()
{
echo -n "test on lines count ($1): "
- if cat "$STD_OUT" | wc -l | grep -q "$1"
+ if [ $(cat "$STD_OUT" | wc -l) -eq "$1" ]
then
pr_success
else
diff --git a/testsuite/tests/bridge/vlan/tunnelshow.t b/testsuite/tests/bridge/vlan/tunnelshow.t
new file mode 100755
index 000000000..fd41bfcb3
--- /dev/null
+++ b/testsuite/tests/bridge/vlan/tunnelshow.t
@@ -0,0 +1,33 @@
+#!/bin/sh
+
+. lib/generic.sh
+
+ts_log "[Testing tunnelshow]"
+
+BR_DEV="$(rand_dev)"
+VX_DEV="$(rand_dev)"
+
+ts_ip "$0" "Add $BR_DEV bridge interface" link add $BR_DEV type bridge
+
+ts_ip "$0" "Add $VX_DEV vxlan interface" \
+ link add $VX_DEV type vxlan dstport 4789 external
+ts_ip "$0" "Enslave $VX_DEV under $BR_DEV" \
+ link set dev $VX_DEV master $BR_DEV
+ts_ip "$0" "Set vlan_tunnel on $VX_DEV" \
+ link set dev $VX_DEV type bridge_slave vlan_tunnel on
+
+ts_bridge "$0" "Add single vlan" vlan add dev $VX_DEV vid 1000
+ts_bridge "$0" "Add single tunnel" \
+ vlan add dev $VX_DEV vid 1000 tunnel_info id 1000
+ts_bridge "$0" "Add vlan range" vlan add dev $VX_DEV vid 1010-1020
+ts_bridge "$0" "Add tunnel range" \
+ vlan add dev $VX_DEV vid 1010-1020 tunnel_info id 1010-1020
+ts_bridge "$0" "Add single vlan" vlan add dev $VX_DEV vid 1030
+ts_bridge "$0" "Add tunnel with vni > 16k" \
+ vlan add dev $VX_DEV vid 1030 tunnel_info id 65556
+
+ts_bridge "$0" "Show tunnel info" vlan tunnelshow dev $VX_DEV
+test_on "1030\s+65556"
+test_lines_count 5
+
+ts_bridge "$0" "Dump tunnel info" -j vlan tunnelshow dev $VX_DEV