]> granicus.if.org Git - strace/commitdiff
rtnl_link: add basic IFLA_INFO_* handling
authorEugene Syromyatnikov <evgsyr@gmail.com>
Fri, 18 May 2018 15:42:18 +0000 (17:42 +0200)
committerDmitry V. Levin <ldv@altlinux.org>
Wed, 6 Jun 2018 15:10:37 +0000 (15:10 +0000)
Dispatch for IFLA_INFO_* attributes should be performed based on the
string provided in a IFLA_INFO_KIND attribute.

* nlattr.h (struct ifla_linkinfo_ctx): New type definition.
* rtnl_link.c (decode_nla_linkinfo_kind): New function.
(ifla_linkinfo_nla_decoders) <IFLA_INFO_KIND>: Use
decode_nla_linkinfo_kind as decoder.
(decode_ifla_linkinfo): Add struct ifla_linkinfo_ctx context, pass it to
the decode_nlattr call as opaque data.

nlattr.h
rtnl_link.c

index 34a36ad02af232135e56f87aef23b7cc4f2feec7..e403fb605afe3a009c5af106c79fd8251d78c782 100644 (file)
--- a/nlattr.h
+++ b/nlattr.h
@@ -44,6 +44,16 @@ struct decode_nla_xlat_opts {
        size_t size;
 };
 
+/*
+ * Used for IFLA_LINKINFO decoding.  Since there are no other indicators
+ * regarding the nature of data except for previously provided string
+ * in an IFLA_LINKINFO_KIND attribute, we have to store it in order to pass
+ * between calls as an opaque data.
+ */
+struct ifla_linkinfo_ctx {
+       char kind[16];
+};
+
 typedef bool (*nla_decoder_t)(struct tcb *, kernel_ulong_t addr,
                              unsigned int len, const void *opaque_data);
 
index 7c64faa622da2d439e31e751ce7e424a74c90853..081600584f1aa8ab233d23ed3cad6910aa7360fa 100644 (file)
@@ -206,8 +206,31 @@ decode_rtnl_link_ifmap(struct tcb *const tcp,
        return true;
 }
 
+bool
+decode_nla_linkinfo_kind(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;
+
+       memset(ctx->kind, '\0', sizeof(ctx->kind));
+
+       if (umovestr(tcp, addr, sizeof(ctx->kind), ctx->kind) <= 0) {
+               /*
+                * If we haven't seen NUL or an error occurred, set kind to
+                * an empty string.
+                */
+               ctx->kind[0] = '\0';
+       }
+
+       printstr_ex(tcp, addr, len, QUOTE_0_TERMINATED);
+
+       return true;
+}
+
 static const nla_decoder_t ifla_linkinfo_nla_decoders[] = {
-       [IFLA_INFO_KIND]        = decode_nla_str,
+       [IFLA_INFO_KIND]        = decode_nla_linkinfo_kind,
        [IFLA_INFO_DATA]        = NULL, /* unimplemented */
        [IFLA_INFO_XSTATS]      = NULL, /* unimplemented */
        [IFLA_INFO_SLAVE_KIND]  = decode_nla_str,
@@ -220,9 +243,11 @@ decode_ifla_linkinfo(struct tcb *const tcp,
                     const unsigned int len,
                     const void *const opaque_data)
 {
+       struct ifla_linkinfo_ctx ctx = { .kind = "", };
+
        decode_nlattr(tcp, addr, len, rtnl_ifla_info_attrs,
                      "IFLA_INFO_???", ifla_linkinfo_nla_decoders,
-                     ARRAY_SIZE(ifla_linkinfo_nla_decoders), opaque_data);
+                     ARRAY_SIZE(ifla_linkinfo_nla_decoders), &ctx);
 
        return true;
 }