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);
|
||||
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
|
||||
size_t strlcpy(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,
|
||||
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)
|
||||
static void __print_link_stats(FILE *fp, struct rtattr *tb[])
|
||||
{
|
||||
const struct rtattr *carrier_changes = tb[IFLA_CARRIER_CHANGES];
|
||||
struct rtnl_link_stats64 _s, *s = &_s;
|
||||
int ret;
|
||||
|
||||
if (tb[IFLA_STATS64]) {
|
||||
struct rtnl_link_stats64 stats = { 0 };
|
||||
ret = get_rtnl_link_stats_rta(s, tb);
|
||||
if (ret < 0)
|
||||
return;
|
||||
|
||||
memcpy(&stats, RTA_DATA(tb[IFLA_STATS64]),
|
||||
MIN(RTA_PAYLOAD(tb[IFLA_STATS64]), sizeof(stats)));
|
||||
if (is_json_context()) {
|
||||
open_json_object((ret == sizeof(*s)) ? "stats64" : "stats");
|
||||
|
||||
print_link_stats64(fp, &stats, carrier_changes);
|
||||
} else if (tb[IFLA_STATS]) {
|
||||
struct rtnl_link_stats stats = { 0 };
|
||||
/* 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);
|
||||
|
||||
memcpy(&stats, RTA_DATA(tb[IFLA_STATS]),
|
||||
MIN(RTA_PAYLOAD(tb[IFLA_STATS]), sizeof(stats)));
|
||||
/* 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();
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/* 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
|
||||
size_t strlcpy(char *dst, const char *src, size_t size)
|
||||
{
|
||||
|
|
|
|||
Loading…
Reference in New Issue