rtnl_link: implement IFLA_INFO_XSTATS decoding
authorEugene Syromyatnikov <evgsyr@gmail.com>
Fri, 18 May 2018 15:45:33 +0000 (17:45 +0200)
committerDmitry V. Levin <ldv@altlinux.org>
Wed, 6 Jun 2018 15:10:37 +0000 (15:10 +0000)
So far, only CAN provides it.

* rtnl_link.c (decode_nla_linkinfo_xstats_can,
decode_nla_linkinfo_xstats): New function.
(ifla_linkinfo_nla_decoders) <IFLA_INFO_XSTATS>: Use
decode_nla_linkinfo_xstats as a decoder.

rtnl_link.c

index 081600584f1aa8ab233d23ed3cad6910aa7360fa..0944ea95410e4a60990378019ea150e3fb712c0f 100644 (file)
@@ -229,10 +229,62 @@ decode_nla_linkinfo_kind(struct tcb *const tcp,
        return true;
 }
 
+bool
+decode_nla_linkinfo_xstats_can(struct tcb *const tcp,
+                              const kernel_ulong_t addr,
+                              const unsigned int len,
+                              const void *const opaque_data)
+{
+       struct strace_can_device_stats {
+               uint32_t bus_error;
+               uint32_t error_warning;
+               uint32_t error_passive;
+               uint32_t bus_off;
+               uint32_t arbitration_lost;
+               uint32_t restarts;
+       } st;
+       const unsigned int def_size = sizeof(st);
+       const unsigned int size = (len >= def_size) ? def_size : 0;
+
+       if (!size)
+               return false;
+
+       if (umoven_or_printaddr(tcp, addr, size, &st))
+               return true;
+
+       PRINT_FIELD_U("{", st, bus_error);
+       PRINT_FIELD_U(", ", st, error_warning);
+       PRINT_FIELD_U(", ", st, error_passive);
+       PRINT_FIELD_U(", ", st, bus_off);
+       PRINT_FIELD_U(", ", st, arbitration_lost);
+       PRINT_FIELD_U(", ", st, restarts);
+       tprints("}");
+
+       return true;
+}
+
+bool
+decode_nla_linkinfo_xstats(struct tcb *const tcp,
+                          const kernel_ulong_t addr,
+                          const unsigned int len,
+                          const void *const opaque_data)
+{
+       struct ifla_linkinfo_ctx *ctx = (void *) opaque_data;
+       nla_decoder_t func = NULL;
+
+       if (!strcmp(ctx->kind, "can"))
+               func = decode_nla_linkinfo_xstats_can;
+
+       if (func)
+               return func(tcp, addr, len, opaque_data);
+
+       return false;
+}
+
 static const nla_decoder_t ifla_linkinfo_nla_decoders[] = {
        [IFLA_INFO_KIND]        = decode_nla_linkinfo_kind,
        [IFLA_INFO_DATA]        = NULL, /* unimplemented */
-       [IFLA_INFO_XSTATS]      = NULL, /* unimplemented */
+       [IFLA_INFO_XSTATS]      = decode_nla_linkinfo_xstats,
        [IFLA_INFO_SLAVE_KIND]  = decode_nla_str,
        [IFLA_INFO_SLAVE_DATA]  = NULL, /* unimplemented */
 };