Merge branch 'master' into next

Signed-off-by: David Ahern <dsahern@gmail.com>
This commit is contained in:
David Ahern 2020-01-02 17:49:45 +00:00
commit 404f2de114
21 changed files with 547 additions and 306 deletions

View File

@ -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);

View File

@ -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]));

View File

@ -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);

View File

@ -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);

View File

@ -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;

View File

@ -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

View File

@ -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),

View File

@ -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),

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

106
tc/q_fq.c
View File

@ -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);
print_lluint(PRINT_ANY, "flows_plimit", " flows_plimit %llu",
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);
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;
}

View File

@ -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));
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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);
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);
st = RTA_DATA(xstats);
return 0;
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);
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 = {

View File

@ -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));
if (qopt_ext && qopt_ext->depth)
fprintf(f, "depth %u ", qopt_ext->depth);
if (qopt_ext && qopt_ext->headdrop)
fprintf(f, "headdrop ");
if (show_details) {
fprintf(f, "flows %u/%u ", qopt->flows, qopt->divisor);
}
fprintf(f, "divisor %u ", qopt->divisor);
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)
print_uint(PRINT_ANY, "depth", "depth %u ", qopt_ext->depth);
if (qopt_ext && qopt_ext->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 (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;
}

View File

@ -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;
}

View File

@ -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"; \

View File

@ -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

View File

@ -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