ip: Introduce get_rtnl_link_stats_rta() to get link statistics
Assume all statistics in ip(8) represented either by IFLA_STATS64 or IFLA_STATS is 64 bit. It is clean that we can store __u32 counters of @struct rtnl_link_stats in __u64 counters in @struct rtnl_link_stats64. New get_rtnl_link_stats_rta() follows __print_link_stats() behaviour on handling of stats attribute: copy no more than size of data structure and no less than attribute length zeroing rest. Drop print_link_stats32() as it's functionality can be handled by 64bit variant. Move code from __print_link_stats() to print_link_stats64() and finally rename print_link_stats64() to __print_link_stats(). More users of introduced function will come in future. Signed-off-by: Serhey Popovych <serhe.popovych@gmail.com> Signed-off-by: David Ahern <dsahern@gmail.com>
This commit is contained in:
parent
fb7b816827
commit
9a7bd5442b
|
|
@ -284,6 +284,9 @@ int make_path(const char *path, mode_t mode);
|
||||||
char *find_cgroup2_mount(void);
|
char *find_cgroup2_mount(void);
|
||||||
int get_command_name(const char *pid, char *comm, size_t len);
|
int get_command_name(const char *pid, char *comm, size_t len);
|
||||||
|
|
||||||
|
int get_rtnl_link_stats_rta(struct rtnl_link_stats64 *stats64,
|
||||||
|
struct rtattr *tb[]);
|
||||||
|
|
||||||
#ifdef NEED_STRLCPY
|
#ifdef NEED_STRLCPY
|
||||||
size_t strlcpy(char *dst, const char *src, size_t size);
|
size_t strlcpy(char *dst, const char *src, size_t size);
|
||||||
size_t strlcat(char *dst, const char *src, size_t size);
|
size_t strlcat(char *dst, const char *src, size_t size);
|
||||||
|
|
|
||||||
431
ip/ipaddress.c
431
ip/ipaddress.c
|
|
@ -593,306 +593,151 @@ static void print_vf_stats64(FILE *fp, struct rtattr *vfstats)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void print_link_stats64(FILE *fp, const struct rtnl_link_stats64 *s,
|
static void __print_link_stats(FILE *fp, struct rtattr *tb[])
|
||||||
const struct rtattr *carrier_changes)
|
|
||||||
{
|
|
||||||
if (is_json_context()) {
|
|
||||||
open_json_object("stats64");
|
|
||||||
|
|
||||||
/* RX stats */
|
|
||||||
open_json_object("rx");
|
|
||||||
print_uint(PRINT_JSON, "bytes", NULL, s->rx_bytes);
|
|
||||||
print_uint(PRINT_JSON, "packets", NULL, s->rx_packets);
|
|
||||||
print_uint(PRINT_JSON, "errors", NULL, s->rx_errors);
|
|
||||||
print_uint(PRINT_JSON, "dropped", NULL, s->rx_dropped);
|
|
||||||
print_uint(PRINT_JSON, "over_errors", NULL, s->rx_over_errors);
|
|
||||||
print_uint(PRINT_JSON, "multicast", NULL, s->multicast);
|
|
||||||
if (s->rx_compressed)
|
|
||||||
print_uint(PRINT_JSON,
|
|
||||||
"compressed", NULL, s->rx_compressed);
|
|
||||||
|
|
||||||
/* RX error stats */
|
|
||||||
if (show_stats > 1) {
|
|
||||||
print_uint(PRINT_JSON,
|
|
||||||
"length_errors",
|
|
||||||
NULL, s->rx_length_errors);
|
|
||||||
print_uint(PRINT_JSON,
|
|
||||||
"crc_errors",
|
|
||||||
NULL, s->rx_crc_errors);
|
|
||||||
print_uint(PRINT_JSON,
|
|
||||||
"frame_errors",
|
|
||||||
NULL, s->rx_frame_errors);
|
|
||||||
print_uint(PRINT_JSON,
|
|
||||||
"fifo_errors",
|
|
||||||
NULL, s->rx_fifo_errors);
|
|
||||||
print_uint(PRINT_JSON,
|
|
||||||
"missed_errors",
|
|
||||||
NULL, s->rx_missed_errors);
|
|
||||||
if (s->rx_nohandler)
|
|
||||||
print_uint(PRINT_JSON,
|
|
||||||
"nohandler", NULL, s->rx_nohandler);
|
|
||||||
}
|
|
||||||
close_json_object();
|
|
||||||
|
|
||||||
/* TX stats */
|
|
||||||
open_json_object("tx");
|
|
||||||
print_uint(PRINT_JSON, "bytes", NULL, s->tx_bytes);
|
|
||||||
print_uint(PRINT_JSON, "packets", NULL, s->tx_packets);
|
|
||||||
print_uint(PRINT_JSON, "errors", NULL, s->tx_errors);
|
|
||||||
print_uint(PRINT_JSON, "dropped", NULL, s->tx_dropped);
|
|
||||||
print_uint(PRINT_JSON,
|
|
||||||
"carrier_errors",
|
|
||||||
NULL, s->tx_carrier_errors);
|
|
||||||
print_uint(PRINT_JSON, "collisions", NULL, s->collisions);
|
|
||||||
if (s->tx_compressed)
|
|
||||||
print_uint(PRINT_JSON,
|
|
||||||
"compressed", NULL, s->tx_compressed);
|
|
||||||
|
|
||||||
/* TX error stats */
|
|
||||||
if (show_stats > 1) {
|
|
||||||
print_uint(PRINT_JSON,
|
|
||||||
"aborted_errors",
|
|
||||||
NULL, s->tx_aborted_errors);
|
|
||||||
print_uint(PRINT_JSON,
|
|
||||||
"fifo_errors",
|
|
||||||
NULL, s->tx_fifo_errors);
|
|
||||||
print_uint(PRINT_JSON,
|
|
||||||
"window_errors",
|
|
||||||
NULL, s->tx_window_errors);
|
|
||||||
print_uint(PRINT_JSON,
|
|
||||||
"heartbeat_errors",
|
|
||||||
NULL, s->tx_heartbeat_errors);
|
|
||||||
if (carrier_changes)
|
|
||||||
print_uint(PRINT_JSON, "carrier_changes", NULL,
|
|
||||||
rta_getattr_u32(carrier_changes));
|
|
||||||
}
|
|
||||||
|
|
||||||
close_json_object();
|
|
||||||
close_json_object();
|
|
||||||
} else {
|
|
||||||
/* RX stats */
|
|
||||||
fprintf(fp, " RX: bytes packets errors dropped overrun mcast %s%s",
|
|
||||||
s->rx_compressed ? "compressed" : "", _SL_);
|
|
||||||
|
|
||||||
fprintf(fp, " ");
|
|
||||||
print_num(fp, 10, s->rx_bytes);
|
|
||||||
print_num(fp, 8, s->rx_packets);
|
|
||||||
print_num(fp, 7, s->rx_errors);
|
|
||||||
print_num(fp, 7, s->rx_dropped);
|
|
||||||
print_num(fp, 7, s->rx_over_errors);
|
|
||||||
print_num(fp, 7, s->multicast);
|
|
||||||
if (s->rx_compressed)
|
|
||||||
print_num(fp, 7, s->rx_compressed);
|
|
||||||
|
|
||||||
/* RX error stats */
|
|
||||||
if (show_stats > 1) {
|
|
||||||
fprintf(fp, "%s", _SL_);
|
|
||||||
fprintf(fp, " RX errors: length crc frame fifo missed%s%s",
|
|
||||||
s->rx_nohandler ? " nohandler" : "", _SL_);
|
|
||||||
fprintf(fp, " ");
|
|
||||||
print_num(fp, 8, s->rx_length_errors);
|
|
||||||
print_num(fp, 7, s->rx_crc_errors);
|
|
||||||
print_num(fp, 7, s->rx_frame_errors);
|
|
||||||
print_num(fp, 7, s->rx_fifo_errors);
|
|
||||||
print_num(fp, 7, s->rx_missed_errors);
|
|
||||||
if (s->rx_nohandler)
|
|
||||||
print_num(fp, 7, s->rx_nohandler);
|
|
||||||
}
|
|
||||||
fprintf(fp, "%s", _SL_);
|
|
||||||
|
|
||||||
/* TX stats */
|
|
||||||
fprintf(fp, " TX: bytes packets errors dropped carrier collsns %s%s",
|
|
||||||
s->tx_compressed ? "compressed" : "", _SL_);
|
|
||||||
|
|
||||||
fprintf(fp, " ");
|
|
||||||
print_num(fp, 10, s->tx_bytes);
|
|
||||||
print_num(fp, 8, s->tx_packets);
|
|
||||||
print_num(fp, 7, s->tx_errors);
|
|
||||||
print_num(fp, 7, s->tx_dropped);
|
|
||||||
print_num(fp, 7, s->tx_carrier_errors);
|
|
||||||
print_num(fp, 7, s->collisions);
|
|
||||||
if (s->tx_compressed)
|
|
||||||
print_num(fp, 7, s->tx_compressed);
|
|
||||||
|
|
||||||
/* TX error stats */
|
|
||||||
if (show_stats > 1) {
|
|
||||||
fprintf(fp, "%s", _SL_);
|
|
||||||
fprintf(fp, " TX errors: aborted fifo window heartbeat");
|
|
||||||
if (carrier_changes)
|
|
||||||
fprintf(fp, " transns");
|
|
||||||
fprintf(fp, "%s", _SL_);
|
|
||||||
|
|
||||||
fprintf(fp, " ");
|
|
||||||
print_num(fp, 8, s->tx_aborted_errors);
|
|
||||||
print_num(fp, 7, s->tx_fifo_errors);
|
|
||||||
print_num(fp, 7, s->tx_window_errors);
|
|
||||||
print_num(fp, 7, s->tx_heartbeat_errors);
|
|
||||||
if (carrier_changes)
|
|
||||||
print_num(fp, 7,
|
|
||||||
rta_getattr_u32(carrier_changes));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void print_link_stats32(FILE *fp, const struct rtnl_link_stats *s,
|
|
||||||
const struct rtattr *carrier_changes)
|
|
||||||
{
|
|
||||||
if (is_json_context()) {
|
|
||||||
open_json_object("stats");
|
|
||||||
|
|
||||||
/* RX stats */
|
|
||||||
open_json_object("rx");
|
|
||||||
print_uint(PRINT_JSON, "bytes", NULL, s->rx_bytes);
|
|
||||||
print_uint(PRINT_JSON, "packets", NULL, s->rx_packets);
|
|
||||||
print_uint(PRINT_JSON, "errors", NULL, s->rx_errors);
|
|
||||||
print_uint(PRINT_JSON, "dropped", NULL, s->rx_dropped);
|
|
||||||
print_uint(PRINT_JSON, "over_errors", NULL, s->rx_over_errors);
|
|
||||||
print_uint(PRINT_JSON, "multicast", NULL, s->multicast);
|
|
||||||
if (s->rx_compressed)
|
|
||||||
print_uint(PRINT_JSON,
|
|
||||||
"compressed", NULL, s->rx_compressed);
|
|
||||||
|
|
||||||
/* RX error stats */
|
|
||||||
if (show_stats > 1) {
|
|
||||||
print_uint(PRINT_JSON,
|
|
||||||
"length_errors",
|
|
||||||
NULL, s->rx_length_errors);
|
|
||||||
print_uint(PRINT_JSON,
|
|
||||||
"crc_errors",
|
|
||||||
NULL, s->rx_crc_errors);
|
|
||||||
print_uint(PRINT_JSON,
|
|
||||||
"frame_errors",
|
|
||||||
NULL, s->rx_frame_errors);
|
|
||||||
print_uint(PRINT_JSON,
|
|
||||||
"fifo_errors",
|
|
||||||
NULL, s->rx_fifo_errors);
|
|
||||||
print_uint(PRINT_JSON,
|
|
||||||
"missed_errors",
|
|
||||||
NULL, s->rx_missed_errors);
|
|
||||||
if (s->rx_nohandler)
|
|
||||||
print_uint(PRINT_JSON,
|
|
||||||
"nohandler", NULL, s->rx_nohandler);
|
|
||||||
}
|
|
||||||
close_json_object();
|
|
||||||
|
|
||||||
/* TX stats */
|
|
||||||
open_json_object("tx");
|
|
||||||
print_uint(PRINT_JSON, "bytes", NULL, s->tx_bytes);
|
|
||||||
print_uint(PRINT_JSON, "packets", NULL, s->tx_packets);
|
|
||||||
print_uint(PRINT_JSON, "errors", NULL, s->tx_errors);
|
|
||||||
print_uint(PRINT_JSON, "dropped", NULL, s->tx_dropped);
|
|
||||||
print_uint(PRINT_JSON,
|
|
||||||
"carrier_errors",
|
|
||||||
NULL, s->tx_carrier_errors);
|
|
||||||
print_uint(PRINT_JSON, "collisions", NULL, s->collisions);
|
|
||||||
if (s->tx_compressed)
|
|
||||||
print_uint(PRINT_JSON,
|
|
||||||
"compressed", NULL, s->tx_compressed);
|
|
||||||
|
|
||||||
/* TX error stats */
|
|
||||||
if (show_stats > 1) {
|
|
||||||
print_uint(PRINT_JSON,
|
|
||||||
"aborted_errors",
|
|
||||||
NULL, s->tx_aborted_errors);
|
|
||||||
print_uint(PRINT_JSON,
|
|
||||||
"fifo_errors",
|
|
||||||
NULL, s->tx_fifo_errors);
|
|
||||||
print_uint(PRINT_JSON,
|
|
||||||
"window_errors",
|
|
||||||
NULL, s->tx_window_errors);
|
|
||||||
print_uint(PRINT_JSON,
|
|
||||||
"heartbeat_errors",
|
|
||||||
NULL, s->tx_heartbeat_errors);
|
|
||||||
if (carrier_changes)
|
|
||||||
print_uint(PRINT_JSON, "carrier_changes", NULL,
|
|
||||||
rta_getattr_u32(carrier_changes));
|
|
||||||
}
|
|
||||||
|
|
||||||
close_json_object();
|
|
||||||
close_json_object();
|
|
||||||
} else {
|
|
||||||
/* RX stats */
|
|
||||||
fprintf(fp, " RX: bytes packets errors dropped overrun mcast %s%s",
|
|
||||||
s->rx_compressed ? "compressed" : "", _SL_);
|
|
||||||
|
|
||||||
fprintf(fp, " ");
|
|
||||||
print_num(fp, 10, s->rx_bytes);
|
|
||||||
print_num(fp, 8, s->rx_packets);
|
|
||||||
print_num(fp, 7, s->rx_errors);
|
|
||||||
print_num(fp, 7, s->rx_dropped);
|
|
||||||
print_num(fp, 7, s->rx_over_errors);
|
|
||||||
print_num(fp, 7, s->multicast);
|
|
||||||
if (s->rx_compressed)
|
|
||||||
print_num(fp, 7, s->rx_compressed);
|
|
||||||
|
|
||||||
/* RX error stats */
|
|
||||||
if (show_stats > 1) {
|
|
||||||
fprintf(fp, "%s", _SL_);
|
|
||||||
fprintf(fp, " RX errors: length crc frame fifo missed%s%s",
|
|
||||||
s->rx_nohandler ? " nohandler" : "", _SL_);
|
|
||||||
fprintf(fp, " ");
|
|
||||||
print_num(fp, 8, s->rx_length_errors);
|
|
||||||
print_num(fp, 7, s->rx_crc_errors);
|
|
||||||
print_num(fp, 7, s->rx_frame_errors);
|
|
||||||
print_num(fp, 7, s->rx_fifo_errors);
|
|
||||||
print_num(fp, 7, s->rx_missed_errors);
|
|
||||||
if (s->rx_nohandler)
|
|
||||||
print_num(fp, 7, s->rx_nohandler);
|
|
||||||
}
|
|
||||||
fprintf(fp, "%s", _SL_);
|
|
||||||
|
|
||||||
/* TX stats */
|
|
||||||
fprintf(fp, " TX: bytes packets errors dropped carrier collsns %s%s",
|
|
||||||
s->tx_compressed ? "compressed" : "", _SL_);
|
|
||||||
|
|
||||||
fprintf(fp, " ");
|
|
||||||
print_num(fp, 10, s->tx_bytes);
|
|
||||||
print_num(fp, 8, s->tx_packets);
|
|
||||||
print_num(fp, 7, s->tx_errors);
|
|
||||||
print_num(fp, 7, s->tx_dropped);
|
|
||||||
print_num(fp, 7, s->tx_carrier_errors);
|
|
||||||
print_num(fp, 7, s->collisions);
|
|
||||||
if (s->tx_compressed)
|
|
||||||
print_num(fp, 7, s->tx_compressed);
|
|
||||||
|
|
||||||
/* TX error stats */
|
|
||||||
if (show_stats > 1) {
|
|
||||||
fprintf(fp, "%s", _SL_);
|
|
||||||
fprintf(fp, " TX errors: aborted fifo window heartbeat");
|
|
||||||
if (carrier_changes)
|
|
||||||
fprintf(fp, " transns");
|
|
||||||
fprintf(fp, "%s", _SL_);
|
|
||||||
|
|
||||||
fprintf(fp, " ");
|
|
||||||
print_num(fp, 8, s->tx_aborted_errors);
|
|
||||||
print_num(fp, 7, s->tx_fifo_errors);
|
|
||||||
print_num(fp, 7, s->tx_window_errors);
|
|
||||||
print_num(fp, 7, s->tx_heartbeat_errors);
|
|
||||||
if (carrier_changes)
|
|
||||||
print_num(fp, 7,
|
|
||||||
rta_getattr_u32(carrier_changes));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void __print_link_stats(FILE *fp, struct rtattr **tb)
|
|
||||||
{
|
{
|
||||||
const struct rtattr *carrier_changes = tb[IFLA_CARRIER_CHANGES];
|
const struct rtattr *carrier_changes = tb[IFLA_CARRIER_CHANGES];
|
||||||
|
struct rtnl_link_stats64 _s, *s = &_s;
|
||||||
|
int ret;
|
||||||
|
|
||||||
if (tb[IFLA_STATS64]) {
|
ret = get_rtnl_link_stats_rta(s, tb);
|
||||||
struct rtnl_link_stats64 stats = { 0 };
|
if (ret < 0)
|
||||||
|
return;
|
||||||
|
|
||||||
memcpy(&stats, RTA_DATA(tb[IFLA_STATS64]),
|
if (is_json_context()) {
|
||||||
MIN(RTA_PAYLOAD(tb[IFLA_STATS64]), sizeof(stats)));
|
open_json_object((ret == sizeof(*s)) ? "stats64" : "stats");
|
||||||
|
|
||||||
print_link_stats64(fp, &stats, carrier_changes);
|
/* RX stats */
|
||||||
} else if (tb[IFLA_STATS]) {
|
open_json_object("rx");
|
||||||
struct rtnl_link_stats stats = { 0 };
|
print_uint(PRINT_JSON, "bytes", NULL, s->rx_bytes);
|
||||||
|
print_uint(PRINT_JSON, "packets", NULL, s->rx_packets);
|
||||||
|
print_uint(PRINT_JSON, "errors", NULL, s->rx_errors);
|
||||||
|
print_uint(PRINT_JSON, "dropped", NULL, s->rx_dropped);
|
||||||
|
print_uint(PRINT_JSON, "over_errors", NULL, s->rx_over_errors);
|
||||||
|
print_uint(PRINT_JSON, "multicast", NULL, s->multicast);
|
||||||
|
if (s->rx_compressed)
|
||||||
|
print_uint(PRINT_JSON,
|
||||||
|
"compressed", NULL, s->rx_compressed);
|
||||||
|
|
||||||
memcpy(&stats, RTA_DATA(tb[IFLA_STATS]),
|
/* RX error stats */
|
||||||
MIN(RTA_PAYLOAD(tb[IFLA_STATS]), sizeof(stats)));
|
if (show_stats > 1) {
|
||||||
|
print_uint(PRINT_JSON,
|
||||||
|
"length_errors",
|
||||||
|
NULL, s->rx_length_errors);
|
||||||
|
print_uint(PRINT_JSON,
|
||||||
|
"crc_errors",
|
||||||
|
NULL, s->rx_crc_errors);
|
||||||
|
print_uint(PRINT_JSON,
|
||||||
|
"frame_errors",
|
||||||
|
NULL, s->rx_frame_errors);
|
||||||
|
print_uint(PRINT_JSON,
|
||||||
|
"fifo_errors",
|
||||||
|
NULL, s->rx_fifo_errors);
|
||||||
|
print_uint(PRINT_JSON,
|
||||||
|
"missed_errors",
|
||||||
|
NULL, s->rx_missed_errors);
|
||||||
|
if (s->rx_nohandler)
|
||||||
|
print_uint(PRINT_JSON,
|
||||||
|
"nohandler", NULL, s->rx_nohandler);
|
||||||
|
}
|
||||||
|
close_json_object();
|
||||||
|
|
||||||
print_link_stats32(fp, &stats, carrier_changes);
|
/* TX stats */
|
||||||
|
open_json_object("tx");
|
||||||
|
print_uint(PRINT_JSON, "bytes", NULL, s->tx_bytes);
|
||||||
|
print_uint(PRINT_JSON, "packets", NULL, s->tx_packets);
|
||||||
|
print_uint(PRINT_JSON, "errors", NULL, s->tx_errors);
|
||||||
|
print_uint(PRINT_JSON, "dropped", NULL, s->tx_dropped);
|
||||||
|
print_uint(PRINT_JSON,
|
||||||
|
"carrier_errors",
|
||||||
|
NULL, s->tx_carrier_errors);
|
||||||
|
print_uint(PRINT_JSON, "collisions", NULL, s->collisions);
|
||||||
|
if (s->tx_compressed)
|
||||||
|
print_uint(PRINT_JSON,
|
||||||
|
"compressed", NULL, s->tx_compressed);
|
||||||
|
|
||||||
|
/* TX error stats */
|
||||||
|
if (show_stats > 1) {
|
||||||
|
print_uint(PRINT_JSON,
|
||||||
|
"aborted_errors",
|
||||||
|
NULL, s->tx_aborted_errors);
|
||||||
|
print_uint(PRINT_JSON,
|
||||||
|
"fifo_errors",
|
||||||
|
NULL, s->tx_fifo_errors);
|
||||||
|
print_uint(PRINT_JSON,
|
||||||
|
"window_errors",
|
||||||
|
NULL, s->tx_window_errors);
|
||||||
|
print_uint(PRINT_JSON,
|
||||||
|
"heartbeat_errors",
|
||||||
|
NULL, s->tx_heartbeat_errors);
|
||||||
|
if (carrier_changes)
|
||||||
|
print_uint(PRINT_JSON, "carrier_changes", NULL,
|
||||||
|
rta_getattr_u32(carrier_changes));
|
||||||
|
}
|
||||||
|
|
||||||
|
close_json_object();
|
||||||
|
close_json_object();
|
||||||
|
} else {
|
||||||
|
/* RX stats */
|
||||||
|
fprintf(fp, " RX: bytes packets errors dropped overrun mcast %s%s",
|
||||||
|
s->rx_compressed ? "compressed" : "", _SL_);
|
||||||
|
|
||||||
|
fprintf(fp, " ");
|
||||||
|
print_num(fp, 10, s->rx_bytes);
|
||||||
|
print_num(fp, 8, s->rx_packets);
|
||||||
|
print_num(fp, 7, s->rx_errors);
|
||||||
|
print_num(fp, 7, s->rx_dropped);
|
||||||
|
print_num(fp, 7, s->rx_over_errors);
|
||||||
|
print_num(fp, 7, s->multicast);
|
||||||
|
if (s->rx_compressed)
|
||||||
|
print_num(fp, 7, s->rx_compressed);
|
||||||
|
|
||||||
|
/* RX error stats */
|
||||||
|
if (show_stats > 1) {
|
||||||
|
fprintf(fp, "%s", _SL_);
|
||||||
|
fprintf(fp, " RX errors: length crc frame fifo missed%s%s",
|
||||||
|
s->rx_nohandler ? " nohandler" : "", _SL_);
|
||||||
|
fprintf(fp, " ");
|
||||||
|
print_num(fp, 8, s->rx_length_errors);
|
||||||
|
print_num(fp, 7, s->rx_crc_errors);
|
||||||
|
print_num(fp, 7, s->rx_frame_errors);
|
||||||
|
print_num(fp, 7, s->rx_fifo_errors);
|
||||||
|
print_num(fp, 7, s->rx_missed_errors);
|
||||||
|
if (s->rx_nohandler)
|
||||||
|
print_num(fp, 7, s->rx_nohandler);
|
||||||
|
}
|
||||||
|
fprintf(fp, "%s", _SL_);
|
||||||
|
|
||||||
|
/* TX stats */
|
||||||
|
fprintf(fp, " TX: bytes packets errors dropped carrier collsns %s%s",
|
||||||
|
s->tx_compressed ? "compressed" : "", _SL_);
|
||||||
|
|
||||||
|
fprintf(fp, " ");
|
||||||
|
print_num(fp, 10, s->tx_bytes);
|
||||||
|
print_num(fp, 8, s->tx_packets);
|
||||||
|
print_num(fp, 7, s->tx_errors);
|
||||||
|
print_num(fp, 7, s->tx_dropped);
|
||||||
|
print_num(fp, 7, s->tx_carrier_errors);
|
||||||
|
print_num(fp, 7, s->collisions);
|
||||||
|
if (s->tx_compressed)
|
||||||
|
print_num(fp, 7, s->tx_compressed);
|
||||||
|
|
||||||
|
/* TX error stats */
|
||||||
|
if (show_stats > 1) {
|
||||||
|
fprintf(fp, "%s", _SL_);
|
||||||
|
fprintf(fp, " TX errors: aborted fifo window heartbeat");
|
||||||
|
if (carrier_changes)
|
||||||
|
fprintf(fp, " transns");
|
||||||
|
fprintf(fp, "%s", _SL_);
|
||||||
|
|
||||||
|
fprintf(fp, " ");
|
||||||
|
print_num(fp, 8, s->tx_aborted_errors);
|
||||||
|
print_num(fp, 7, s->tx_fifo_errors);
|
||||||
|
print_num(fp, 7, s->tx_window_errors);
|
||||||
|
print_num(fp, 7, s->tx_heartbeat_errors);
|
||||||
|
if (carrier_changes)
|
||||||
|
print_num(fp, 7,
|
||||||
|
rta_getattr_u32(carrier_changes));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
45
lib/utils.c
45
lib/utils.c
|
|
@ -1431,6 +1431,51 @@ int get_real_family(int rtm_type, int rtm_family)
|
||||||
return rtm_family;
|
return rtm_family;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Based on copy_rtnl_link_stats() from kernel at net/core/rtnetlink.c */
|
||||||
|
static void copy_rtnl_link_stats64(struct rtnl_link_stats64 *stats64,
|
||||||
|
const struct rtnl_link_stats *stats)
|
||||||
|
{
|
||||||
|
__u64 *a = (__u64 *)stats64;
|
||||||
|
const __u32 *b = (const __u32 *)stats;
|
||||||
|
const __u32 *e = b + sizeof(*stats) / sizeof(*b);
|
||||||
|
|
||||||
|
while (b < e)
|
||||||
|
*a++ = *b++;
|
||||||
|
}
|
||||||
|
|
||||||
|
int get_rtnl_link_stats_rta(struct rtnl_link_stats64 *stats64,
|
||||||
|
struct rtattr *tb[])
|
||||||
|
{
|
||||||
|
struct rtnl_link_stats stats;
|
||||||
|
void *s;
|
||||||
|
struct rtattr *rta;
|
||||||
|
int size, len;
|
||||||
|
|
||||||
|
if (tb[IFLA_STATS64]) {
|
||||||
|
rta = tb[IFLA_STATS64];
|
||||||
|
size = sizeof(struct rtnl_link_stats64);
|
||||||
|
s = stats64;
|
||||||
|
} else if (tb[IFLA_STATS]) {
|
||||||
|
rta = tb[IFLA_STATS];
|
||||||
|
size = sizeof(struct rtnl_link_stats);
|
||||||
|
s = &stats;
|
||||||
|
} else {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
len = RTA_PAYLOAD(rta);
|
||||||
|
if (len < size)
|
||||||
|
memset(s + len, 0, size - len);
|
||||||
|
else
|
||||||
|
len = size;
|
||||||
|
|
||||||
|
memcpy(s, RTA_DATA(rta), len);
|
||||||
|
|
||||||
|
if (s != stats64)
|
||||||
|
copy_rtnl_link_stats64(stats64, s);
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef NEED_STRLCPY
|
#ifdef NEED_STRLCPY
|
||||||
size_t strlcpy(char *dst, const char *src, size_t size)
|
size_t strlcpy(char *dst, const char *src, size_t size)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue