]> git.proxmox.com Git - mirror_iproute2.git/blobdiff - lib/utils.c
bpf: check map symbol type properly with newer llvm compiler
[mirror_iproute2.git] / lib / utils.c
index 802075fca874d6ec689c71d4d06d8b30c19667e4..345630d04929dbe82a82fb19721b9ea36695993a 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/param.h>
 #include <linux/if_arp.h>
 #include <linux/mpls.h>
+#include <linux/snmp.h>
 #include <time.h>
 #include <sys/time.h>
 #include <errno.h>
@@ -42,6 +43,7 @@
 int resolve_hosts;
 int timestamp_short;
 int pretty;
+const char *_SL_ = "\n";
 
 int read_prop(const char *dev, char *prop, long *value)
 {
@@ -382,6 +384,27 @@ int get_u8(__u8 *val, const char *arg, int base)
        return 0;
 }
 
+int get_s64(__s64 *val, const char *arg, int base)
+{
+       long res;
+       char *ptr;
+
+       errno = 0;
+
+       if (!arg || !*arg)
+               return -1;
+       res = strtoll(arg, &ptr, base);
+       if (!ptr || ptr == arg || *ptr)
+               return -1;
+       if ((res == LLONG_MIN || res == LLONG_MAX) && errno == ERANGE)
+               return -1;
+       if (res > INT64_MAX || res < INT64_MIN)
+               return -1;
+
+       *val = res;
+       return 0;
+}
+
 int get_s32(__s32 *val, const char *arg, int base)
 {
        long res;
@@ -1434,7 +1457,7 @@ int makeargs(char *line, char *argv[], int maxargs)
                                break;
                }
 
-               /* seperate words */
+               /* separate words */
                *cp++ = 0;
        }
        argv[argc] = NULL;
@@ -1548,6 +1571,24 @@ static void copy_rtnl_link_stats64(struct rtnl_link_stats64 *stats64,
                *a++ = *b++;
 }
 
+#define IPSTATS_MIB_MAX_LEN    (__IPSTATS_MIB_MAX * sizeof(__u64))
+static void get_snmp_counters(struct rtnl_link_stats64 *stats64,
+                             struct rtattr *s)
+{
+       __u64 *mib = (__u64 *)RTA_DATA(s);
+
+       memset(stats64, 0, sizeof(*stats64));
+
+       stats64->rx_packets = mib[IPSTATS_MIB_INPKTS];
+       stats64->rx_bytes = mib[IPSTATS_MIB_INOCTETS];
+       stats64->tx_packets = mib[IPSTATS_MIB_OUTPKTS];
+       stats64->tx_bytes = mib[IPSTATS_MIB_OUTOCTETS];
+       stats64->rx_errors = mib[IPSTATS_MIB_INDISCARDS];
+       stats64->tx_errors = mib[IPSTATS_MIB_OUTDISCARDS];
+       stats64->multicast = mib[IPSTATS_MIB_INMCASTPKTS];
+       stats64->rx_frame_errors = mib[IPSTATS_MIB_CSUMERRORS];
+}
+
 int get_rtnl_link_stats_rta(struct rtnl_link_stats64 *stats64,
                            struct rtattr *tb[])
 {
@@ -1564,6 +1605,14 @@ int get_rtnl_link_stats_rta(struct rtnl_link_stats64 *stats64,
                rta = tb[IFLA_STATS];
                size = sizeof(struct rtnl_link_stats);
                s = &stats;
+       } else if (tb[IFLA_PROTINFO]) {
+               struct rtattr *ptb[IPSTATS_MIB_MAX_LEN + 1];
+
+               parse_rtattr_nested(ptb, IPSTATS_MIB_MAX_LEN,
+                                   tb[IFLA_PROTINFO]);
+               if (ptb[IFLA_INET6_STATS])
+                       get_snmp_counters(stats64, ptb[IFLA_INET6_STATS]);
+               return sizeof(*stats64);
        } else {
                return -1;
        }