From 7503a0f9e41d28ce046cd4fda4042d2978e4508e Mon Sep 17 00:00:00 2001 From: Eugene Syromyatnikov Date: Fri, 18 May 2018 17:42:18 +0200 Subject: [PATCH] rtnl_link: add basic IFLA_INFO_* handling 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) : 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 | 10 ++++++++++ rtnl_link.c | 29 +++++++++++++++++++++++++++-- 2 files changed, 37 insertions(+), 2 deletions(-) diff --git a/nlattr.h b/nlattr.h index 34a36ad0..e403fb60 100644 --- 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); diff --git a/rtnl_link.c b/rtnl_link.c index 7c64faa6..08160058 100644 --- a/rtnl_link.c +++ b/rtnl_link.c @@ -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; } -- 2.40.0