|
|
930fb9 |
From 2e4e707b662df2cf505147ca19da94ef97b6ea25 Mon Sep 17 00:00:00 2001
|
|
|
930fb9 |
From: Phil Sutter <psutter@redhat.com>
|
|
|
930fb9 |
Date: Thu, 18 Oct 2018 12:51:12 +0200
|
|
|
930fb9 |
Subject: [PATCH] utils: fix get_rtnl_link_stats_rta stats parsing
|
|
|
930fb9 |
|
|
|
930fb9 |
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1626306
|
|
|
930fb9 |
Upstream Status: iproute2.git commit c7a3b22961f52
|
|
|
930fb9 |
|
|
|
930fb9 |
commit c7a3b22961f528760766aa85095eb1ab04a39797
|
|
|
930fb9 |
Author: Lorenzo Bianconi <lorenzo.bianconi@redhat.com>
|
|
|
930fb9 |
Date: Wed Oct 10 17:00:58 2018 +0200
|
|
|
930fb9 |
|
|
|
930fb9 |
utils: fix get_rtnl_link_stats_rta stats parsing
|
|
|
930fb9 |
|
|
|
930fb9 |
iproute2 walks through the list of available tunnels using netlink
|
|
|
930fb9 |
protocol in order to get device info instead of reading
|
|
|
930fb9 |
them from proc filesystem. However the kernel reports device statistics
|
|
|
930fb9 |
using IFLA_INET6_STATS/IFLA_INET6_ICMP6STATS attributes nested in
|
|
|
930fb9 |
IFLA_PROTINFO one but iproutes expects these info in
|
|
|
930fb9 |
IFLA_STATS64/IFLA_STATS attributes.
|
|
|
930fb9 |
The issue can be triggered with the following reproducer:
|
|
|
930fb9 |
|
|
|
930fb9 |
$ip link add ip6d0 type ip6tnl mode ip6ip6 local 1111::1 remote 2222::1
|
|
|
930fb9 |
$ip -6 -d -s tunnel show ip6d0
|
|
|
930fb9 |
ip6d0: ipv6/ipv6 remote 2222::1 local 1111::1 encaplimit 4 hoplimit 64
|
|
|
930fb9 |
tclass 0x00 flowlabel 0x00000 (flowinfo 0x00000000)
|
|
|
930fb9 |
Dump terminated
|
|
|
930fb9 |
|
|
|
930fb9 |
Fix the issue introducing IFLA_INET6_STATS attribute parsing
|
|
|
930fb9 |
|
|
|
930fb9 |
Fixes: 3e953938717f ("iptunnel/ip6tunnel: Use netlink to walk through
|
|
|
930fb9 |
tunnels list")
|
|
|
930fb9 |
|
|
|
930fb9 |
Signed-off-by: Lorenzo Bianconi <lorenzo.bianconi@redhat.com>
|
|
|
930fb9 |
---
|
|
|
930fb9 |
lib/utils.c | 27 +++++++++++++++++++++++++++
|
|
|
930fb9 |
1 file changed, 27 insertions(+)
|
|
|
930fb9 |
|
|
|
930fb9 |
diff --git a/lib/utils.c b/lib/utils.c
|
|
|
930fb9 |
index e87ecf3..7be2d6b 100644
|
|
|
930fb9 |
--- a/lib/utils.c
|
|
|
930fb9 |
+++ b/lib/utils.c
|
|
|
930fb9 |
@@ -27,6 +27,7 @@
|
|
|
930fb9 |
#include <linux/param.h>
|
|
|
930fb9 |
#include <linux/if_arp.h>
|
|
|
930fb9 |
#include <linux/mpls.h>
|
|
|
930fb9 |
+#include <linux/snmp.h>
|
|
|
930fb9 |
#include <time.h>
|
|
|
930fb9 |
#include <sys/time.h>
|
|
|
930fb9 |
#include <errno.h>
|
|
|
930fb9 |
@@ -1549,6 +1550,24 @@ static void copy_rtnl_link_stats64(struct rtnl_link_stats64 *stats64,
|
|
|
930fb9 |
*a++ = *b++;
|
|
|
930fb9 |
}
|
|
|
930fb9 |
|
|
|
930fb9 |
+#define IPSTATS_MIB_MAX_LEN (__IPSTATS_MIB_MAX * sizeof(__u64))
|
|
|
930fb9 |
+static void get_snmp_counters(struct rtnl_link_stats64 *stats64,
|
|
|
930fb9 |
+ struct rtattr *s)
|
|
|
930fb9 |
+{
|
|
|
930fb9 |
+ __u64 *mib = (__u64 *)RTA_DATA(s);
|
|
|
930fb9 |
+
|
|
|
930fb9 |
+ memset(stats64, 0, sizeof(*stats64));
|
|
|
930fb9 |
+
|
|
|
930fb9 |
+ stats64->rx_packets = mib[IPSTATS_MIB_INPKTS];
|
|
|
930fb9 |
+ stats64->rx_bytes = mib[IPSTATS_MIB_INOCTETS];
|
|
|
930fb9 |
+ stats64->tx_packets = mib[IPSTATS_MIB_OUTPKTS];
|
|
|
930fb9 |
+ stats64->tx_bytes = mib[IPSTATS_MIB_OUTOCTETS];
|
|
|
930fb9 |
+ stats64->rx_errors = mib[IPSTATS_MIB_INDISCARDS];
|
|
|
930fb9 |
+ stats64->tx_errors = mib[IPSTATS_MIB_OUTDISCARDS];
|
|
|
930fb9 |
+ stats64->multicast = mib[IPSTATS_MIB_INMCASTPKTS];
|
|
|
930fb9 |
+ stats64->rx_frame_errors = mib[IPSTATS_MIB_CSUMERRORS];
|
|
|
930fb9 |
+}
|
|
|
930fb9 |
+
|
|
|
930fb9 |
int get_rtnl_link_stats_rta(struct rtnl_link_stats64 *stats64,
|
|
|
930fb9 |
struct rtattr *tb[])
|
|
|
930fb9 |
{
|
|
|
930fb9 |
@@ -1565,6 +1584,14 @@ int get_rtnl_link_stats_rta(struct rtnl_link_stats64 *stats64,
|
|
|
930fb9 |
rta = tb[IFLA_STATS];
|
|
|
930fb9 |
size = sizeof(struct rtnl_link_stats);
|
|
|
930fb9 |
s = &stat;;
|
|
|
930fb9 |
+ } else if (tb[IFLA_PROTINFO]) {
|
|
|
930fb9 |
+ struct rtattr *ptb[IPSTATS_MIB_MAX_LEN + 1];
|
|
|
930fb9 |
+
|
|
|
930fb9 |
+ parse_rtattr_nested(ptb, IPSTATS_MIB_MAX_LEN,
|
|
|
930fb9 |
+ tb[IFLA_PROTINFO]);
|
|
|
930fb9 |
+ if (ptb[IFLA_INET6_STATS])
|
|
|
930fb9 |
+ get_snmp_counters(stats64, ptb[IFLA_INET6_STATS]);
|
|
|
930fb9 |
+ return sizeof(*stats64);
|
|
|
930fb9 |
} else {
|
|
|
930fb9 |
return -1;
|
|
|
930fb9 |
}
|
|
|
930fb9 |
--
|
|
|
930fb9 |
1.8.3.1
|
|
|
930fb9 |
|