This is first step to move tunnel code to use rtnl dump interface instead of /proc/net/dev read.
Make tnl_print_stats() to accept @struct rtnl_link_stats64 parameter, introduce tnl_get_stats() that will parse line from /proc/net/dev into @struct rtnl_link_stats64. Signed-off-by: Serhey Popovych <serhe.popov...@gmail.com> --- ip/ip6tunnel.c | 8 ++++++-- ip/iptunnel.c | 8 ++++++-- ip/tunnel.c | 57 +++++++++++++++++++++++++++++++++++--------------------- ip/tunnel.h | 5 ++++- 4 files changed, 52 insertions(+), 26 deletions(-) diff --git a/ip/ip6tunnel.c b/ip/ip6tunnel.c index 783e28a..3e99559 100644 --- a/ip/ip6tunnel.c +++ b/ip/ip6tunnel.c @@ -390,8 +390,12 @@ static int do_tunnels_list(struct ip6_tnl_parm2 *p) if (!ip6_tnl_parm_match(p, &p1)) continue; print_tunnel(&p1); - if (show_stats) - tnl_print_stats(ptr); + if (show_stats) { + struct rtnl_link_stats64 s; + + if (!tnl_get_stats(ptr, &s)) + tnl_print_stats(&s); + } printf("\n"); } err = 0; diff --git a/ip/iptunnel.c b/ip/iptunnel.c index 0aa3b33..6639055 100644 --- a/ip/iptunnel.c +++ b/ip/iptunnel.c @@ -425,8 +425,12 @@ static int do_tunnels_list(struct ip_tunnel_parm *p) (p->i_key && p1.i_key != p->i_key)) continue; print_tunnel(&p1); - if (show_stats) - tnl_print_stats(ptr); + if (show_stats) { + struct rtnl_link_stats64 s; + + if (!tnl_get_stats(ptr, &s)) + tnl_print_stats(&s); + } printf("\n"); } err = 0; diff --git a/ip/tunnel.c b/ip/tunnel.c index 948d5f7..06533cf 100644 --- a/ip/tunnel.c +++ b/ip/tunnel.c @@ -307,30 +307,45 @@ void tnl_print_endpoint(const char *name, const struct rtattr *rta, int family) } } -/* tnl_print_stats - print tunnel statistics - * - * @buf - tunnel interface's line in /proc/net/dev, - * starting past the interface name and following colon - */ -void tnl_print_stats(const char *buf) +int tnl_get_stats(const char *buf, struct rtnl_link_stats64 *s) { - unsigned long rx_bytes, rx_packets, rx_errs, rx_drops, - rx_fifo, rx_frame, - tx_bytes, tx_packets, tx_errs, tx_drops, - tx_fifo, tx_colls, tx_carrier, rx_multi; - - if (sscanf(buf, "%lu%lu%lu%lu%lu%lu%lu%*d%lu%lu%lu%lu%lu%lu%lu", - &rx_bytes, &rx_packets, &rx_errs, &rx_drops, - &rx_fifo, &rx_frame, &rx_multi, - &tx_bytes, &tx_packets, &tx_errs, &tx_drops, - &tx_fifo, &tx_colls, &tx_carrier) != 14) - return; + /* rx */ + __u64 *rx_bytes = &s->rx_bytes; + __u64 *rx_packets = &s->rx_packets; + __u64 *rx_errs = &s->rx_errors; + __u64 *rx_drops = &s->rx_dropped; + __u64 *rx_fifo = &s->rx_fifo_errors; + __u64 *rx_frame = &s->rx_frame_errors; + __u64 *rx_multi = &s->multicast; + /* tx */ + __u64 *tx_bytes = &s->tx_bytes; + __u64 *tx_packets = &s->tx_packets; + __u64 *tx_errs = &s->tx_errors; + __u64 *tx_drops = &s->tx_dropped; + __u64 *tx_fifo = &s->tx_fifo_errors; + __u64 *tx_carrier = &s->tx_carrier_errors; + __u64 *tx_colls = &s->collisions; + + if (sscanf(buf, + "%llu%llu%llu%llu%llu%llu%llu%*d%llu%llu%llu%llu%llu%llu%llu", + rx_bytes, rx_packets, rx_errs, rx_drops, + rx_fifo, rx_frame, rx_multi, + tx_bytes, tx_packets, tx_errs, tx_drops, + tx_fifo, tx_colls, tx_carrier) != 14) + return -1; + return 0; +} + +void tnl_print_stats(const struct rtnl_link_stats64 *s) +{ printf("%s", _SL_); printf("RX: Packets Bytes Errors CsumErrs OutOfSeq Mcasts%s", _SL_); - printf(" %-10ld %-12ld %-6ld %-8ld %-8ld %-8ld%s", - rx_packets, rx_bytes, rx_errs, rx_frame, rx_fifo, rx_multi, _SL_); + printf(" %-10lld %-12lld %-6lld %-8lld %-8lld %-8lld%s", + s->rx_packets, s->rx_bytes, s->rx_errors, s->rx_frame_errors, + s->rx_fifo_errors, s->multicast, _SL_); printf("TX: Packets Bytes Errors DeadLoop NoRoute NoBufs%s", _SL_); - printf(" %-10ld %-12ld %-6ld %-8ld %-8ld %-6ld", - tx_packets, tx_bytes, tx_errs, tx_colls, tx_carrier, tx_drops); + printf(" %-10lld %-12lld %-6lld %-8lld %-8lld %-6lld", + s->tx_packets, s->tx_bytes, s->tx_errors, s->collisions, + s->tx_carrier_errors, s->tx_dropped); } diff --git a/ip/tunnel.h b/ip/tunnel.h index 5bd27c3..5fe488b 100644 --- a/ip/tunnel.h +++ b/ip/tunnel.h @@ -24,6 +24,7 @@ #include <linux/types.h> struct rtattr; +struct rtnl_link_stats64; const char *tnl_strproto(__u8 proto); @@ -39,6 +40,8 @@ void tnl_print_encap(struct rtattr *tb[], int encap_sport, int encap_dport); void tnl_print_endpoint(const char *name, const struct rtattr *rta, int family); -void tnl_print_stats(const char *buf); +void tnl_print_stats(const struct rtnl_link_stats64 *s); + +int tnl_get_stats(const char *buf, struct rtnl_link_stats64 *s); #endif -- 1.7.10.4